package com.red.circle.other.app.command.sys;

import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.other.app.convertor.sys.OauthAccessTokenAppConvertor;
import com.red.circle.other.app.dto.clientobject.sys.OauthAccessTokenCO;
import com.red.circle.other.app.dto.cmd.sys.OauthCertificateCmd;
import com.red.circle.other.infra.database.cache.service.other.OauthCacheService;
import com.red.circle.other.infra.database.cache.token.OauthAccessTokenCertificate;
import com.red.circle.other.infra.database.rds.entity.sys.OauthRegister;
import com.red.circle.other.infra.database.rds.service.sys.OauthRegisterService;
import com.red.circle.other.inner.asserts.user.UserErrorCode;
import java.util.Objects;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * @author pengliang on 2022/5/10
 */
@Component
@RequiredArgsConstructor
public class OauthLoginCmdExe {

  private final OauthCacheService oauthCacheService;
  private final OauthRegisterService oauthRegisterService;
  private OauthAccessTokenAppConvertor oauthAccessTokenAppConvertor;

  public OauthAccessTokenCO execute(OauthCertificateCmd cmd) {
    OauthRegister oauthRegister = oauthRegisterService.getById(cmd.getSecretId());
    ResponseAssert.notNull(UserErrorCode.ACCOUNT_OR_PASSWORD_NOT_MATCH, oauthRegister);
    ResponseAssert.isTrue(UserErrorCode.ACCOUNT_OR_PASSWORD_NOT_MATCH,
        Objects.equals(oauthRegister.getSecretKey(), cmd.getSecretKey()));
    ResponseAssert.isTrue(UserErrorCode.ACCOUNT_CLOSED,
        Objects.equals("RUN", oauthRegister.getStatus()));
    return Optional.ofNullable(oauthAccessTokenAppConvertor.toOauthAccessTokenCo(
            oauthCacheService.addToken(new OauthAccessTokenCertificate()
                .setUserId(oauthRegister.getUserId())
                .setSecretId(oauthRegister.getSecretId())
                .setSecretKey(oauthRegister.getSecretKey())
                .setExpiredTime(oauthRegister.getExpiredTime())
            )
        )
    ).orElse(null);
  }

}
