package com.cloudhandson.vpdbackoffice.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

/** Fails startup when an advertised ADB Agent Tool cannot actually be called. */
@Component
public class McpAgentToolStartupValidator implements SmartInitializingSingleton {

  static final String TOOL_METADATA_SQL = """
      SELECT TOOL_NAME, STATUS
      FROM USER_AI_AGENT_TOOLS
      """;

  private static final Logger log =
      LoggerFactory.getLogger(McpAgentToolStartupValidator.class);

  private final McpToolCatalog toolCatalog;
  private final JdbcTemplate jdbcTemplate;

  public McpAgentToolStartupValidator(
      McpToolCatalog toolCatalog,
      JdbcTemplate jdbcTemplate
  ) {
    this.toolCatalog = toolCatalog;
    this.jdbcTemplate = jdbcTemplate;
  }

  @Override
  public void afterSingletonsInstantiated() {
    validateAdvertisedAgentTools();
  }

  void validateAdvertisedAgentTools() {
    Set<String> requiredTargets = new TreeSet<>();
    toolCatalog.tools().stream()
        .filter(McpToolDefinition::agentTool)
        .map(McpToolDefinition::targetName)
        .map(value -> value.toUpperCase(Locale.ROOT))
        .forEach(requiredTargets::add);

    if (requiredTargets.isEmpty()) {
      log.info("MCP startup validation skipped: no ADB Agent Tool is advertised");
      return;
    }

    Map<String, String> registered = loadRegisteredTools();
    List<String> missing = new ArrayList<>();
    List<String> notEnabled = new ArrayList<>();
    for (String requiredTarget : requiredTargets) {
      if (!registered.containsKey(requiredTarget)) {
        missing.add(requiredTarget);
        continue;
      }
      String status = registered.get(requiredTarget);
      if (!"ENABLED".equals(status)) {
        notEnabled.add(requiredTarget + "=" + status);
      }
    }

    if (!missing.isEmpty() || !notEnabled.isEmpty()) {
      throw new IllegalStateException(
          "Advertised MCP Agent Tool validation failed: missing=" + missing
              + ", notEnabled=" + notEnabled);
    }

    log.info("Validated {} advertised ADB Agent Tool(s): {}",
        requiredTargets.size(), requiredTargets);
  }

  private Map<String, String> loadRegisteredTools() {
    try {
      Map<String, String> registered = new TreeMap<>();
      for (Map<String, Object> row : jdbcTemplate.queryForList(TOOL_METADATA_SQL)) {
        String toolName = normalized(row, "TOOL_NAME");
        if (!toolName.isBlank()) {
          String status = normalized(row, "STATUS");
          registered.put(toolName, status.isBlank() ? "<NULL>" : status);
        }
      }
      return registered;
    } catch (DataAccessException exception) {
      throw new IllegalStateException(
          "Unable to validate advertised MCP Agent Tools in USER_AI_AGENT_TOOLS",
          exception);
    }
  }

  private String normalized(Map<String, Object> row, String column) {
    Object value = row.get(column);
    if (value == null) {
      value = row.entrySet().stream()
          .filter(entry -> column.equalsIgnoreCase(entry.getKey()))
          .map(Map.Entry::getValue)
          .findFirst()
          .orElse(null);
    }
    return value == null ? "" : value.toString().trim().toUpperCase(Locale.ROOT);
  }
}
