package com.cloudhandson.ddsbackoffice.config;

import java.net.URI;
import java.time.Duration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.bind.ConstructorBinding;

/**
 * OCI IAM client-credentials settings for the DDS MCP service identity.
 *
 * <p>The client credential proves the service may attach a DDS context; it
 * is never used as the identity of an MCP caller.</p>
 */
@ConfigurationProperties(prefix = "dds.mcp.iam")
public record DdsMcpIamProperties(
    String domainUrl,
    String tokenUri,
    String clientId,
    String clientSecret,
    String databaseScope,
    Duration timeout,
    Duration refreshSkew
) {

  @ConstructorBinding
  public DdsMcpIamProperties {
    domainUrl = trim(domainUrl);
    tokenUri = trim(tokenUri);
    clientId = trim(clientId);
    clientSecret = clientSecret == null ? "" : clientSecret;
    databaseScope = trim(databaseScope);
    timeout = timeout == null || timeout.isNegative() || timeout.isZero()
        ? Duration.ofSeconds(10) : timeout;
    refreshSkew = refreshSkew == null || refreshSkew.isNegative()
        ? Duration.ofSeconds(60) : refreshSkew;
  }

  public boolean configured() {
    return !clientId.isBlank()
        && !clientSecret.isBlank()
        && !databaseScope.isBlank()
        && !resolvedTokenUri().isBlank();
  }

  public URI tokenEndpoint() {
    String value = resolvedTokenUri();
    if (value.isBlank()) {
      throw new IllegalStateException("DDS OCI IAM token endpoint가 설정되지 않았습니다.");
    }
    URI endpoint;
    try {
      endpoint = URI.create(value);
    } catch (IllegalArgumentException exception) {
      throw new IllegalStateException("DDS OCI IAM token endpoint 형식이 올바르지 않습니다.");
    }
    if (!"https".equalsIgnoreCase(endpoint.getScheme())
        || endpoint.getHost() == null
        || endpoint.getUserInfo() != null) {
      throw new IllegalStateException("DDS OCI IAM token endpoint는 HTTPS URL이어야 합니다.");
    }
    return endpoint;
  }

  private String resolvedTokenUri() {
    if (!tokenUri.isBlank()) {
      return tokenUri;
    }
    if (domainUrl.isBlank()) {
      return "";
    }
    return domainUrl.endsWith("/")
        ? domainUrl + "oauth2/v1/token"
        : domainUrl + "/oauth2/v1/token";
  }

  private static String trim(String value) {
    return value == null ? "" : value.trim();
  }
}
