package com.cloudhandson.vpdbackoffice.service;

import com.cloudhandson.vpdbackoffice.config.MaskingProperties;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;
import org.springframework.stereotype.Service;

/** Loads the managed redaction policy allow-list from BACKOFFICE_MASKING_POLICIES. */
@Service
public class EnvironmentMaskingPolicyCatalog implements MaskingPolicyCatalog {
  private static final Pattern NAME = Pattern.compile("[A-Z][A-Z0-9_$#]{0,127}");
  private final List<MaskingPolicyTarget> targets;

  public EnvironmentMaskingPolicyCatalog(MaskingProperties properties, ObjectMapper objectMapper) {
    targets = parse(properties.policies(), objectMapper);
  }

  @Override
  public List<MaskingPolicyTarget> targets() {
    return targets;
  }

  private List<MaskingPolicyTarget> parse(String raw, ObjectMapper objectMapper) {
    if (raw == null || raw.isBlank()) {
      return List.of();
    }
    try {
      List<MaskingPolicyTarget> parsed = objectMapper.readValue(raw, new TypeReference<>() {});
      if (parsed.isEmpty()
          || parsed.stream().map(MaskingPolicyTarget::objectName).distinct().count() != parsed.size()) {
        throw new IllegalArgumentException();
      }
      List<MaskingPolicyTarget> normalized = parsed.stream()
          .map(item -> new MaskingPolicyTarget(normalize(item.objectName()), normalize(item.policyName())))
          .toList();
      return List.copyOf(normalized);
    } catch (Exception exception) {
      throw new IllegalStateException("BACKOFFICE_MASKING_POLICIES 설정을 확인하세요.", exception);
    }
  }

  private String normalize(String value) {
    String normalized = value == null ? "" : value.trim().toUpperCase(Locale.ROOT);
    if (!NAME.matcher(normalized).matches()) {
      throw new IllegalArgumentException();
    }
    return normalized;
  }
}
