import { execSync } from "child_process";
import { createHash } from "crypto";
import { logger } from "../monitoring/logger.js";
class ProjectIsolationManager {
  static instance;
  projectCache = /* @__PURE__ */ new Map();
  static getInstance() {
    if (!ProjectIsolationManager.instance) {
      ProjectIsolationManager.instance = new ProjectIsolationManager();
    }
    return ProjectIsolationManager.instance;
  }
  /**
   * Get stable project identification based on git remote URL
   */
  getProjectIdentification(projectRoot) {
    const cacheKey = projectRoot;
    if (this.projectCache.has(cacheKey)) {
      return this.projectCache.get(cacheKey);
    }
    try {
      const remoteUrl = this.getGitRemoteUrl(projectRoot);
      const gitInfo = this.parseGitRemote(remoteUrl);
      const projectId = this.createStableProjectId(gitInfo.organization, gitInfo.repository);
      const workspaceFilter = this.createWorkspaceFilter(gitInfo.organization, gitInfo.repository, projectRoot);
      const linearConfig = this.getLinearConfiguration(gitInfo.organization, gitInfo.repository, projectRoot);
      const identification = {
        projectId,
        organization: gitInfo.organization,
        repository: gitInfo.repository,
        workspaceFilter,
        linearTeamId: linearConfig.teamId,
        linearOrganization: linearConfig.organization,
        projectPrefix: linearConfig.prefix
      };
      this.projectCache.set(cacheKey, identification);
      logger.info("Project identification created", {
        projectId: identification.projectId,
        workspaceFilter: identification.workspaceFilter,
        linearTeam: identification.linearTeamId
      });
      return identification;
    } catch (error) {
      logger.warn("Could not determine git remote, using fallback identification", { error });
      const fallback = this.createFallbackIdentification(projectRoot);
      this.projectCache.set(cacheKey, fallback);
      return fallback;
    }
  }
  /**
   * Find git repository root and get remote URL
   */
  getGitRemoteUrl(projectRoot) {
    try {
      const gitRoot = execSync("git rev-parse --show-toplevel", {
        cwd: projectRoot,
        encoding: "utf8",
        timeout: 5e3
      }).trim();
      const result = execSync("git config --get remote.origin.url", {
        cwd: gitRoot,
        encoding: "utf8",
        timeout: 5e3
      });
      return result.trim();
    } catch (error) {
      throw new Error(`Failed to get git remote URL: ${error}`);
    }
  }
  /**
   * Get project name from git repository root directory
   */
  getProjectNameFromGitRoot(projectRoot) {
    try {
      const gitRoot = execSync("git rev-parse --show-toplevel", {
        cwd: projectRoot,
        encoding: "utf8",
        timeout: 5e3
      }).trim();
      return gitRoot.split("/").pop() || "unknown";
    } catch (error) {
      return projectRoot.split("/").pop() || "unknown";
    }
  }
  /**
   * Parse git remote URL to extract organization and repository
   */
  parseGitRemote(remoteUrl) {
    let match = remoteUrl.match(/github\.com[/:]([\w-]+)\/([\w-]+)(?:\.git)?/);
    if (match) {
      return {
        organization: match[1],
        repository: match[2]
      };
    }
    match = remoteUrl.match(/[:/]([\w-]+)\/([\w-]+)(?:\.git)?$/);
    if (match) {
      return {
        organization: match[1],
        repository: match[2]
      };
    }
    throw new Error(`Could not parse git remote URL: ${remoteUrl}`);
  }
  /**
   * Create stable project ID from organization and repository
   */
  createStableProjectId(organization, repository) {
    const content = `${organization}/${repository}`;
    const hash = createHash("sha256").update(content).digest("hex");
    return `proj-${hash.substring(0, 12)}`;
  }
  /**
   * Create stable workspace filter using git root folder name
   */
  createWorkspaceFilter(organization, repository, projectRoot) {
    const projectName = this.getProjectNameFromGitRoot(projectRoot);
    return `${projectName}:${organization}`;
  }
  /**
   * Get Linear configuration based on project
   */
  getLinearConfiguration(organization, repository, projectRoot) {
    const projectName = projectRoot ? this.getProjectNameFromGitRoot(projectRoot) : repository;
    const projectConfigs = {
      "jonathanpeterwu/stackmemory": {
        teamId: process.env.LINEAR_TEAM_ID || "stackmemory",
        organization: process.env.LINEAR_ORGANIZATION || "stackmemoryai",
        prefix: "SM"
      },
      "Lift-Coefficient/*": {
        teamId: "STA",
        organization: "lift-cl",
        prefix: "STA"
      }
    };
    const exactKey = `${organization}/${repository}`;
    if (projectConfigs[exactKey]) {
      return projectConfigs[exactKey];
    }
    const wildcardKey = `${organization}/*`;
    if (projectConfigs[wildcardKey]) {
      return projectConfigs[wildcardKey];
    }
    const sanitizedProjectName = projectName.replace(/[^a-zA-Z0-9]/g, "");
    return {
      teamId: sanitizedProjectName.toLowerCase(),
      organization: `${organization.toLowerCase()}ai`,
      prefix: sanitizedProjectName.substring(0, 3).toUpperCase()
    };
  }
  /**
   * Create fallback identification for non-git projects
   */
  createFallbackIdentification(projectRoot) {
    const folderName = projectRoot.split("/").pop() || "unknown";
    const projectId = this.createStableProjectId("local", folderName);
    return {
      projectId,
      organization: "local",
      repository: folderName,
      workspaceFilter: `local:${folderName}`,
      linearTeamId: folderName.toLowerCase().replace(/[^a-z0-9]/g, ""),
      linearOrganization: "local",
      projectPrefix: folderName.substring(0, 3).toUpperCase()
    };
  }
  /**
   * Validate that current project isolation is working
   */
  validateProjectIsolation(projectRoot) {
    try {
      const identification = this.getProjectIdentification(projectRoot);
      if (!identification.projectId || !identification.workspaceFilter) {
        return false;
      }
      const secondCall = this.getProjectIdentification(projectRoot);
      if (identification.workspaceFilter !== secondCall.workspaceFilter) {
        return false;
      }
      return true;
    } catch (error) {
      logger.error("Project isolation validation failed", { error });
      return false;
    }
  }
  /**
   * Clear project cache (for testing)
   */
  clearCache() {
    this.projectCache.clear();
  }
}
export {
  ProjectIsolationManager
};
//# sourceMappingURL=project-isolation.js.map
