import { fileURLToPath as __fileURLToPath } from 'url';
import { dirname as __pathDirname } from 'path';
const __filename = __fileURLToPath(import.meta.url);
const __dirname = __pathDirname(__filename);
import { execSync } from "child_process";
import * as fs from "fs";
import * as path from "path";
import * as os from "os";
import { logger } from "../core/monitoring/logger.js";
class APISkill {
  registryPath;
  restishConfigPath;
  registry;
  constructor() {
    this.registryPath = path.join(
      os.homedir(),
      ".stackmemory",
      "api-registry.json"
    );
    this.restishConfigPath = process.platform === "darwin" ? path.join(
      os.homedir(),
      "Library",
      "Application Support",
      "restish",
      "apis.json"
    ) : path.join(os.homedir(), ".config", "restish", "apis.json");
    this.registry = this.loadRegistry();
  }
  loadRegistry() {
    try {
      if (fs.existsSync(this.registryPath)) {
        return JSON.parse(fs.readFileSync(this.registryPath, "utf-8"));
      }
    } catch (error) {
      logger.warn("Failed to load API registry:", error);
    }
    return { apis: {}, version: "1.0.0" };
  }
  saveRegistry() {
    const dir = path.dirname(this.registryPath);
    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir, { recursive: true });
    }
    fs.writeFileSync(this.registryPath, JSON.stringify(this.registry, null, 2));
  }
  /**
   * Load restish config
   */
  loadRestishConfig() {
    try {
      if (fs.existsSync(this.restishConfigPath)) {
        return JSON.parse(fs.readFileSync(this.restishConfigPath, "utf-8"));
      }
    } catch (error) {
      logger.warn("Failed to load restish config:", error);
    }
    return {};
  }
  /**
   * Save restish config
   */
  saveRestishConfig(config) {
    const dir = path.dirname(this.restishConfigPath);
    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir, { recursive: true });
    }
    fs.writeFileSync(this.restishConfigPath, JSON.stringify(config, null, 2));
  }
  /**
   * Check if restish is installed
   */
  checkRestish() {
    try {
      execSync("which restish", { stdio: "pipe" });
      return true;
    } catch {
      return false;
    }
  }
  /**
   * Add/register a new API
   */
  async add(name, baseUrl, options) {
    if (!this.checkRestish()) {
      return {
        success: false,
        message: "restish not installed. Run: brew install restish"
      };
    }
    try {
      const restishConfig = this.loadRestishConfig();
      const apiConfig = {
        base: baseUrl
      };
      if (options?.spec) {
        apiConfig.spec_files = [options.spec];
      }
      if (options?.authType === "api-key" && options?.envVar) {
        apiConfig.profiles = {
          default: {
            headers: {
              [options.headerName || "Authorization"]: `$${options.envVar}`
            }
          }
        };
      }
      restishConfig[name] = apiConfig;
      this.saveRestishConfig(restishConfig);
      const config = {
        name,
        baseUrl,
        specUrl: options?.spec,
        authType: options?.authType || "none",
        authConfig: {
          headerName: options?.headerName || "Authorization",
          envVar: options?.envVar
        },
        registeredAt: (/* @__PURE__ */ new Date()).toISOString()
      };
      if (options?.spec) {
        config.specUrl = options.spec;
      }
      this.registry.apis[name] = config;
      this.saveRegistry();
      return {
        success: true,
        message: `API '${name}' registered successfully`,
        data: {
          name,
          baseUrl,
          authType: config.authType,
          operations: config.operations?.length || "auto-discovered"
        }
      };
    } catch (error) {
      logger.error("Failed to add API:", error);
      return {
        success: false,
        message: `Failed to register API: ${error.message}`
      };
    }
  }
  /**
   * Discover available operations for an API
   */
  discoverOperations(apiName) {
    try {
      const output = execSync(`restish ${apiName} --help 2>&1`, {
        encoding: "utf-8",
        stdio: ["pipe", "pipe", "pipe"]
      });
      const operations = [];
      const lines = output.split("\n");
      let inCommands = false;
      for (const line of lines) {
        if (line.includes("Available Commands:")) {
          inCommands = true;
          continue;
        }
        if (inCommands && line.trim()) {
          const match = line.match(/^\s+(\S+)/);
          if (match && !line.includes("help")) {
            operations.push(match[1]);
          }
        }
        if (inCommands && line.includes("Flags:")) {
          break;
        }
      }
      return operations;
    } catch {
      return [];
    }
  }
  /**
   * List registered APIs
   */
  async list() {
    const apis = Object.values(this.registry.apis);
    if (apis.length === 0) {
      return {
        success: true,
        message: "No APIs registered. Use /api add <name> <url> to register one.",
        data: []
      };
    }
    return {
      success: true,
      message: `${apis.length} API(s) registered`,
      data: apis.map((api) => ({
        name: api.name,
        baseUrl: api.baseUrl,
        authType: api.authType,
        operations: api.operations?.length || "unknown",
        registeredAt: api.registeredAt
      }))
    };
  }
  /**
   * Show details for a specific API
   */
  async describe(apiName, operation) {
    const api = this.registry.apis[apiName];
    if (!api) {
      try {
        const output = execSync(`restish api show ${apiName}`, {
          encoding: "utf-8",
          stdio: ["pipe", "pipe", "pipe"]
        });
        return {
          success: true,
          message: `API '${apiName}' (from restish config)`,
          data: { raw: output }
        };
      } catch {
        return {
          success: false,
          message: `API '${apiName}' not found`
        };
      }
    }
    if (operation) {
      try {
        const output = execSync(`restish ${apiName} ${operation} --help`, {
          encoding: "utf-8",
          stdio: ["pipe", "pipe", "pipe"]
        });
        return {
          success: true,
          message: `Operation: ${apiName}.${operation}`,
          data: {
            operation,
            help: output
          }
        };
      } catch {
        return {
          success: false,
          message: `Operation '${operation}' not found for API '${apiName}'`
        };
      }
    }
    const operations = this.discoverOperations(apiName);
    api.operations = operations;
    this.saveRegistry();
    return {
      success: true,
      message: `API: ${apiName}`,
      data: {
        ...api,
        operations
      }
    };
  }
  /**
   * Execute an API operation
   */
  async exec(apiName, operation, params, options) {
    if (!this.checkRestish()) {
      return {
        success: false,
        message: "restish not installed. Run: brew install restish"
      };
    }
    const api = this.registry.apis[apiName];
    if (!api) {
      return {
        success: false,
        message: `API '${apiName}' not registered. Use /api add first.`
      };
    }
    const urlPath = operation.startsWith("/") ? operation : `/${operation}`;
    const fullUrl = `${api.baseUrl}${urlPath}`;
    const args = ["get", fullUrl];
    if (options?.raw) {
      args.push("--rsh-raw");
    }
    if (options?.filter) {
      args.push("--rsh-filter", options.filter);
    }
    if (api?.authConfig?.envVar) {
      const token = process.env[api.authConfig.envVar];
      if (token) {
        const headerName = api.authConfig.headerName || "Authorization";
        args.push("-H", `${headerName}:${token}`);
      }
    }
    if (options?.headers) {
      for (const [key, value] of Object.entries(options.headers)) {
        args.push("-H", `${key}:${value}`);
      }
    }
    if (params) {
      for (const [key, value] of Object.entries(params)) {
        args.push("-q", `${key}=${String(value)}`);
      }
    }
    args.push("-o", "json");
    try {
      logger.info(`Executing: restish ${args.join(" ")}`);
      const output = execSync(`restish ${args.join(" ")}`, {
        encoding: "utf-8",
        stdio: ["pipe", "pipe", "pipe"],
        env: process.env
      });
      let data;
      try {
        data = JSON.parse(output);
      } catch {
        data = output;
      }
      return {
        success: true,
        message: `${apiName} ${operation} executed`,
        data
      };
    } catch (error) {
      const stderr = error.stderr?.toString() || error.message;
      logger.error(`API exec failed:`, stderr);
      return {
        success: false,
        message: `API call failed: ${stderr}`
      };
    }
  }
  /**
   * Configure authentication for an API
   */
  async auth(apiName, options) {
    const api = this.registry.apis[apiName];
    if (!api) {
      return {
        success: false,
        message: `API '${apiName}' not registered. Use /api add first.`
      };
    }
    if (options.token) {
      const envVar = options.envVar || `${apiName.toUpperCase()}_API_KEY`;
      process.env[envVar] = options.token;
      api.authType = "api-key";
      api.authConfig = {
        ...api.authConfig,
        envVar
      };
      this.saveRegistry();
      return {
        success: true,
        message: `Auth configured for '${apiName}'. Token stored in ${envVar}`,
        data: { envVar }
      };
    }
    if (options.oauth) {
      try {
        const scopeArg = options.scopes ? `--scopes=${options.scopes.join(",")}` : "";
        execSync(`restish api configure ${apiName} --auth=oauth2 ${scopeArg}`, {
          stdio: "inherit"
        });
        api.authType = "oauth2";
        this.saveRegistry();
        return {
          success: true,
          message: `OAuth2 configured for '${apiName}'`
        };
      } catch (error) {
        return {
          success: false,
          message: `OAuth setup failed: ${error.message}`
        };
      }
    }
    return {
      success: false,
      message: "Specify --token or --oauth"
    };
  }
  /**
   * Remove an API
   */
  async remove(apiName) {
    if (!this.registry.apis[apiName]) {
      return {
        success: false,
        message: `API '${apiName}' not found`
      };
    }
    delete this.registry.apis[apiName];
    this.saveRegistry();
    return {
      success: true,
      message: `API '${apiName}' removed`
    };
  }
  /**
   * Sync API spec (refresh operations)
   */
  async sync(apiName) {
    if (!this.checkRestish()) {
      return {
        success: false,
        message: "restish not installed. Run: brew install restish"
      };
    }
    try {
      execSync(`restish api sync ${apiName}`, { stdio: "pipe" });
      const operations = this.discoverOperations(apiName);
      if (this.registry.apis[apiName]) {
        this.registry.apis[apiName].operations = operations;
        this.saveRegistry();
      }
      return {
        success: true,
        message: `API '${apiName}' synced`,
        data: { operations }
      };
    } catch (error) {
      return {
        success: false,
        message: `Sync failed: ${error.message}`
      };
    }
  }
  /**
   * Get help for the API skill
   */
  getHelp() {
    return `
/api - OpenAPI-based API access via Restish

Commands:
  /api add <name> <url> [--spec <url>] [--auth-type api-key|oauth2]
      Register a new API

  /api list
      List all registered APIs

  /api describe <name> [operation]
      Show API details or specific operation

  /api exec <name> <operation> [--param value...]
      Execute an API operation

  /api auth <name> --token <token> [--env-var NAME]
      Configure API authentication

  /api auth <name> --oauth [--scopes scope1,scope2]
      Configure OAuth2 authentication

  /api sync <name>
      Refresh API operations from spec

  /api remove <name>
      Remove a registered API

Examples:
  /api add github https://api.github.com --spec https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json
  /api auth github --token "$GITHUB_TOKEN"
  /api exec github repos list-for-user --username octocat
  /api exec github issues list --owner microsoft --repo vscode --state open

Built on restish (https://rest.sh) for automatic OpenAPI discovery.
`;
  }
}
let apiSkillInstance = null;
function getAPISkill() {
  if (!apiSkillInstance) {
    apiSkillInstance = new APISkill();
  }
  return apiSkillInstance;
}
export {
  APISkill,
  getAPISkill
};
//# sourceMappingURL=api-skill.js.map
