import { exec } from 'child_process';
import { promisify } from 'util';
import type { ToolResult } from '../../types/index.js';
import type { ToolWithMetadata } from '../types.js';
import { loadDescription } from '../load_description.js';
import { getPermissionManager } from '../../permission/index.js';

const execAsync = promisify(exec);

export const gitPushTool: ToolWithMetadata = {
  name: 'git_push',
  description: loadDescription('git_push'),
  metadata: {
    name: 'git_push',
    category: 'git',
    description: '推送 Git 变更到远程仓库',
    keywords: ['git', 'push', '推送', 'upload', '上传', 'remote'],
    deferLoading: false,
  },
  parameters: {
    remote: {
      type: 'string',
      description: '远程仓库名（默认 origin）',
      required: false,
    },
    branch: {
      type: 'string',
      description: '分支名（默认当前分支）',
      required: false,
    },
    force: {
      type: 'boolean',
      description: '强制推送（--force，危险操作）',
      required: false,
    },
    set_upstream: {
      type: 'boolean',
      description: '设置上游分支（-u）',
      required: false,
    },
    tags: {
      type: 'boolean',
      description: '推送所有标签（--tags）',
      required: false,
    },
  },
  execute: async (params: Record<string, unknown>): Promise<ToolResult> => {
    const remote = (params.remote as string) || 'origin';
    const branch = params.branch as string | undefined;
    const force = params.force as boolean;
    const setUpstream = params.set_upstream as boolean;
    const tags = params.tags as boolean;

    // 权限检查
    const permissionManager = getPermissionManager();
    const permResult = await permissionManager.checkGitPermission({
      operation: 'push',
      remote,
      target: branch,
      force,
    });

    if (!permResult.allowed) {
      if (permResult.needsConfirmation) {
        return {
          success: false,
          output: '',
          error: `需要用户确认: git push${force ? ' --force' : ''}\n原因: ${permResult.reason || '需要权限确认'}`,
        };
      }
      return {
        success: false,
        output: '',
        error: `权限被拒绝: ${permResult.reason || '操作不被允许'}`,
      };
    }

    // 强制推送警告
    if (force) {
      // 这里权限系统已经处理了确认，但可以添加额外的输出
    }

    try {
      const args: string[] = ['push'];

      if (setUpstream) {
        args.push('-u');
      }

      if (force) {
        args.push('--force');
      }

      if (tags) {
        args.push('--tags');
      }

      args.push(remote);

      if (branch) {
        args.push(branch);
      }

      const { stdout, stderr } = await execAsync(`git ${args.join(' ')}`, {
        cwd: process.cwd(),
        timeout: 120000, // 推送可能需要更长时间
      });

      // git push 的输出通常在 stderr
      const output = stdout || stderr || '推送成功';

      return {
        success: true,
        output,
      };
    } catch (error) {
      const execError = error as { stdout?: string; stderr?: string; message: string };

      // 检查常见错误
      const errorMsg = execError.stderr || execError.message;

      if (errorMsg.includes('rejected')) {
        return {
          success: false,
          output: execError.stdout || '',
          error: `推送被拒绝。远程分支有新的提交，请先执行 git_pull 拉取更新。\n${errorMsg}`,
        };
      }

      if (errorMsg.includes('no upstream')) {
        return {
          success: false,
          output: execError.stdout || '',
          error: `当前分支没有设置上游分支。请使用 set_upstream: true 参数。\n${errorMsg}`,
        };
      }

      return {
        success: false,
        output: execError.stdout || '',
        error: errorMsg,
      };
    }
  },
};
