import * as fs from 'fs'
import * as path from 'path'

export const ROOT_DIR = path.join(__dirname, '..')
export const AGENTS_SKILLS_DIR = path.join(ROOT_DIR, '.agents', 'skills')
export const CLAUDE_SKILLS_DIR = path.join(ROOT_DIR, '.claude', 'skills')
export const AGENTS_SKILLS_GITIGNORE = path.join(AGENTS_SKILLS_DIR, '.gitignore')
export const CLAUDE_SKILLS_GITIGNORE = path.join(CLAUDE_SKILLS_DIR, '.gitignore')
export const PUBLIC_SKILLS_FILE = path.join(AGENTS_SKILLS_DIR, 'public-skills.txt')

const SKILL_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/

export function listSkillNames(): string[] {
  const content = readFileSafe(PUBLIC_SKILLS_FILE)
  if (content === null) {
    throw new Error('.agents/skills/public-skills.txt is missing')
  }

  const names: string[] = []
  const seen = new Set<string>()
  const lines = content.split('\n')

  for (const [index, rawLine] of lines.entries()) {
    const trimmedLine = rawLine.trim()
    if (trimmedLine === '' || trimmedLine.startsWith('#')) {
      continue
    }

    if (trimmedLine.includes('#')) {
      throw new Error(
        `inline comments are not allowed at .agents/skills/public-skills.txt:${index + 1}; ` +
          'put comments on the previous line'
      )
    }

    const name = trimmedLine

    if (!SKILL_NAME_PATTERN.test(name)) {
      throw new Error(`invalid skill name '${name}' at .agents/skills/public-skills.txt:${index + 1}`)
    }

    if (seen.has(name)) {
      throw new Error(`duplicate skill name '${name}' at .agents/skills/public-skills.txt:${index + 1}`)
    }

    seen.add(name)
    names.push(name)
  }

  return names.sort((a, b) => a.localeCompare(b))
}

export function buildAgentsSkillsGitignore(skillNames: string[]): string {
  const lines = [
    '# AUTO-GENERATED by `pnpm skills:sync`.',
    '# Do not edit manually.',
    '*',
    '!.gitignore',
    '!README*.md',
    '!public-skills.txt'
  ]

  for (const skillName of skillNames) {
    lines.push(`!${skillName}/`)
    lines.push(`!${skillName}/**`)
  }

  return `${lines.join('\n')}\n`
}

export function buildClaudeSkillsGitignore(skillNames: string[]): string {
  const lines = [
    '# AUTO-GENERATED by `pnpm skills:sync`.',
    '# Do not edit manually.',
    '*',
    '!.gitignore',
    '!README*.md'
  ]

  for (const skillName of skillNames) {
    lines.push(`!${skillName}`)
  }

  return `${lines.join('\n')}\n`
}

export function writeFileIfChanged(filePath: string, content: string): boolean {
  let current = ''
  try {
    current = fs.readFileSync(filePath, 'utf-8')
  } catch (error) {
    const nodeError = error as NodeJS.ErrnoException
    if (nodeError.code !== 'ENOENT') {
      throw error
    }
  }
  if (current === content) {
    return false
  }
  fs.writeFileSync(filePath, content, 'utf-8')
  return true
}

export function readFileSafe(filePath: string): string | null {
  if (!fs.existsSync(filePath)) {
    return null
  }
  return fs.readFileSync(filePath, 'utf-8')
}
