/** 설치 대상 식별자 */
export type TargetId =
  | "claude-code"
  | "codex"
  | "cursor"
  | "zcode"
  | "agents"
  | "antigravity"
  | "gemini-cli"
  | "windsurf"
  | "copilot"
  | "agents-md";

/** 설치 범위 — user: 홈 디렉터리 전역, project: 현재 프로젝트 */
export type Scope = "user" | "project";

/** 한 파일에 대한 설치 동작 */
export type FileAction =
  | { kind: "write"; path: string; content: string }
  /** 마커 블록으로 감싼 영역만 교체(사용자 문서 보존) */
  | { kind: "inject"; path: string; marker: string; content: string };

/** 설치 전 사용자에게 보여줄 계획 */
export interface InstallPlan {
  target: TargetId;
  scope: Scope;
  /** 이 타깃이 파일을 쓰는 루트 (표시용) */
  root: string;
  actions: FileAction[];
  /** 이미 설치돼 있는가 */
  alreadyInstalled: boolean;
  /** 설치를 막는 사유. 있으면 apply 하지 않는다 */
  blocked?: string;
}

/** 매니페스트에 기록되는 개별 파일 */
export interface InstalledFile {
  path: string;
  /** 설치 시점 내용의 sha256 — 사용자 수정(드리프트) 감지에 쓴다 */
  sha256: string;
  /** 마커 주입 방식으로 설치된 파일인가 */
  marker?: string;
}

export interface InstallRecord {
  target: TargetId;
  scope: Scope;
  root: string;
  version: string;
  installedAt: string;
  files: InstalledFile[];
}

export interface Manifest {
  /** 매니페스트 스키마 버전 — 향후 마이그레이션 판단용 */
  schema: 1;
  installs: InstallRecord[];
}

/** doctor/update 가 쓰는 드리프트 판정 */
export type DriftStatus = "ok" | "modified" | "missing";

export interface DriftReport {
  record: InstallRecord;
  files: { path: string; status: DriftStatus }[];
  /** 사용자가 수정한 파일 경로 */
  modified: string[];
}

/** 타깃 어댑터가 구현해야 하는 인터페이스 */
export interface TargetAdapter {
  id: TargetId;
  /** TUI 에 표시할 이름 */
  label: string;
  /** 한 줄 설명 */
  hint: string;
  /** 이 타깃이 지원하는 범위 */
  scopes: Scope[];
  /** 시스템에 이 도구가 설치돼 있는 흔적이 있는가 (기본 선택 여부 판단) */
  detect(ctx: TargetContext): Promise<boolean>;
  /** 설치 계획 수립 — 파일을 쓰지 않는다 */
  plan(ctx: TargetContext): Promise<InstallPlan>;
}

export interface TargetContext {
  scope: Scope;
  /** 홈 디렉터리 */
  home: string;
  /** 현재 작업 디렉터리(프로젝트 범위일 때 기준) */
  cwd: string;
  /** 번들된 스킬 소스 */
  skill: SkillSource;
}

/** 번들에 포함된 스킬 원본 */
export interface SkillSource {
  version: string;
  /** SKILL.md 본문 (프론트매터 포함) */
  skillMd: string;
  /** references/ 이하 상대경로 → 내용 */
  files: Map<string, string>;
  /** 프론트매터를 제외한 본문 — 프론트매터를 쓰지 않는 포맷용 */
  body: string;
  /** 프론트매터에서 뽑은 description */
  description: string;
}
