/**
 * Git LFS 大文件支持模块
 * 参考 Cline 的 LFS 模式检测
 */

import * as fs from 'fs/promises';
import * as path from 'path';
import { minimatch } from 'minimatch';

/**
 * LFS 模式加载器
 * 从 .gitattributes 文件中加载 LFS 模式
 */
export class LFSPatternLoader {
  private patterns: string[] = [];
  private loaded = false;

  /**
   * 从工作目录加载 LFS 模式
   */
  async loadPatterns(workDir: string): Promise<void> {
    const gitattributesPath = path.join(workDir, '.gitattributes');

    try {
      const content = await fs.readFile(gitattributesPath, 'utf-8');
      this.patterns = this.parseLfsPatterns(content);
      this.loaded = true;
    } catch {
      // .gitattributes 不存在或无法读取
      this.patterns = [];
      this.loaded = true;
    }
  }

  /**
   * 解析 .gitattributes 内容，提取 LFS 模式
   */
  private parseLfsPatterns(content: string): string[] {
    const patterns: string[] = [];

    for (const line of content.split('\n')) {
      const trimmed = line.trim();

      // 跳过空行和注释
      if (!trimmed || trimmed.startsWith('#')) {
        continue;
      }

      // 匹配 LFS 配置行: pattern filter=lfs diff=lfs merge=lfs -text
      // 或简单形式: pattern filter=lfs
      if (trimmed.includes('filter=lfs')) {
        // 提取模式（第一个空白字符前的部分）
        const match = trimmed.match(/^(\S+)/);
        if (match) {
          patterns.push(match[1]);
        }
      }
    }

    return patterns;
  }

  /**
   * 检查文件是否为 LFS 管理的文件
   */
  isLfsFile(filePath: string): boolean {
    if (!this.loaded) {
      return false;
    }

    // 规范化路径（使用正斜杠）
    const normalizedPath = filePath.replace(/\\/g, '/');

    return this.patterns.some((pattern) =>
      minimatch(normalizedPath, pattern, { matchBase: true })
    );
  }

  /**
   * 获取所有 LFS 模式
   */
  getPatterns(): string[] {
    return [...this.patterns];
  }

  /**
   * 获取排除模式（用于 .gitignore）
   */
  getExcludePatterns(): string[] {
    return this.patterns.map((p) => {
      // 确保模式以 / 开头（相对于仓库根目录）
      if (!p.startsWith('/') && !p.startsWith('*')) {
        return `/${p}`;
      }
      return p;
    });
  }

  /**
   * 检查是否已加载
   */
  isLoaded(): boolean {
    return this.loaded;
  }

  /**
   * 重置（清除已加载的模式）
   */
  reset(): void {
    this.patterns = [];
    this.loaded = false;
  }

  /**
   * 过滤文件列表，排除 LFS 文件
   */
  filterNonLfsFiles(files: string[]): string[] {
    return files.filter((file) => !this.isLfsFile(file));
  }

  /**
   * 获取 LFS 文件列表
   */
  filterLfsFiles(files: string[]): string[] {
    return files.filter((file) => this.isLfsFile(file));
  }
}

/**
 * 常见的大文件扩展名（作为 LFS 候选）
 */
export const COMMON_LARGE_FILE_EXTENSIONS = [
  // 图片
  '.psd',
  '.ai',
  '.eps',
  '.tiff',
  '.raw',
  '.cr2',
  '.nef',
  // 视频
  '.mp4',
  '.mov',
  '.avi',
  '.mkv',
  '.wmv',
  '.flv',
  // 音频
  '.mp3',
  '.wav',
  '.flac',
  '.aac',
  '.ogg',
  // 压缩文件
  '.zip',
  '.tar',
  '.gz',
  '.rar',
  '.7z',
  // 二进制
  '.exe',
  '.dll',
  '.so',
  '.dylib',
  // 数据文件
  '.db',
  '.sqlite',
  '.mdb',
  // 其他
  '.pdf',
  '.docx',
  '.xlsx',
  '.pptx',
];

/**
 * 检查文件扩展名是否为常见大文件类型
 */
export function isCommonLargeFile(filePath: string): boolean {
  const ext = path.extname(filePath).toLowerCase();
  return COMMON_LARGE_FILE_EXTENSIONS.includes(ext);
}

/**
 * 创建 LFS 模式加载器实例
 */
export function createLFSPatternLoader(): LFSPatternLoader {
  return new LFSPatternLoader();
}
