import { exec } from 'child_process';
import path from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const __rootPath = path.resolve(__dirname, '../../');

const GLOBAL_DATA = {
  gitLock: false,
  buildLock: false,
};

/**
 * 拉取指定仓库的代码
 * @param {string} repoPath 仓库路径
 * @returns {Promise<string>} 拉取结果
 */
const gitPull = (repoPath) => {
  if (GLOBAL_DATA.gitLock) {
    return Promise.reject(new Error('git is locked'));
  }
  GLOBAL_DATA.gitLock = true;
  return new Promise((resolve, reject) => {
    const cwd = path.resolve(repoPath);
    exec("git pull", { cwd }, (error, stdout, stderr) => {
      GLOBAL_DATA.gitLock = false;
      if (error) {
        reject(new Error(stderr) || error);
        return;
      }
      resolve(stdout || "No output");
    });
  });
}

/**
 * 拉当前项目的代码
 */
const gitPullCurrent = () => {
  return gitPull(__rootPath);
}

/**
 * 启动服务
 * @param {string} serviceName 服务名称
 * @returns {Promise<string>} 启动结果
 */
const pm2Start = (serviceName) => {
  // if (process.env.NODE_ENV == 'development') {
  //   return Promise.resolve('development mode, skip');
  // }
  return new Promise((resolve, reject) => {
    exec(`pm2 start ${serviceName}`, (error, stdout, stderr) => {
      if (error) {
        reject(new Error(stderr) || error);
        return;
      }
      resolve(stdout || "No output");
    });
  });
}

/**
 * 停止服务
 * @param {string} serviceName 服务名称
 * @returns {Promise<string>} 停止结果
 */
const pm2Stop = (serviceName) => {
  // if (process.env.NODE_ENV == 'development') {
  //   return Promise.resolve('development mode, skip');
  // }
  return new Promise((resolve, reject) => {
    exec(`pm2 stop ${serviceName}`, (error, stdout, stderr) => {
      if (error) {
        reject(new Error(stderr) || error);
        return;
      }
      resolve(stdout || "No output");
    });
  });
}

/**
 * PM2 重启服务
 * @param {string} serviceName 服务名称
 * @returns {Promise<string>} 重启结果
 */
const pm2Restart = (serviceName) => {
  // if (process.env.NODE_ENV == 'development') {
  //   return Promise.resolve('development mode, skip');
  // }
  return new Promise((resolve, reject) => {
    exec(`pm2 restart ${serviceName}`, (error, stdout, stderr) => {
      if (error) {
        reject(new Error(stderr) || error);
        return;
      }
      resolve(stdout || "No output");
    });
  });
}

/**
 * 清除缓存
 */
const clearCache = (cachePath) => {
  return new Promise((resolve, reject) => {
    exec(`rm -rf ${cachePath}/*`, (error, stdout, stderr) => {
      if (error) {
        reject(new Error(stderr) || error);
        return;
      }
      resolve(stdout || "No output");
    });
  });
}

/**
 * 清除缓存并重启服务
 */
const pm2RestartClearCache = async (serviceName, cachePath) => {
  const stopResult = await pm2Stop(serviceName);
  const clearResult = await clearCache(cachePath);
  const startResult = await pm2Start(serviceName);
  return [stopResult, clearResult, startResult].join('\n\n\n====================\n\n\n');
}

/**
 * PM2 重启 sporttery 服务
 * @param {boolean} hot 是否热重启
 * @returns {Promise<string>} 重启结果
 */
const pm2RestartSporttery = (hot) => {
  if (hot) {
    return pm2Restart('sporttery');
  }
  else {
    return pm2RestartClearCache('sporttery', path.resolve(__rootPath, 'server/data'));
  }
}

/**
 * PM2 重启 pinnacle 服务
 * @param {boolean} hot 是否热重启
 * @returns {Promise<string>} 重启结果
 */
const pm2RestartPinnacle = (hot) => {
  if (hot) {
    return pm2Restart('pinnacle');
  }
  else {
    return pm2RestartClearCache('pinnacle', path.resolve(__rootPath, 'pinnacle/data'));
  }
}

/**
 * 发布 web 服务
 */
const releaseWeb = () => {
  if (GLOBAL_DATA.buildLock) {
    return Promise.reject(new Error('build is locked'));
  }
  GLOBAL_DATA.buildLock = true;
  const webRootPath = path.resolve(__rootPath, 'web');
  return new Promise((resolve, reject) => {
    exec('pnpm run build:antd', { cwd: webRootPath }, (error, stdout, stderr) => {
      GLOBAL_DATA.buildLock = false;
      if (error) {
        reject(new Error(stderr) || error);
        return;
      }
      resolve(stdout || "No output");
    });
  });
}

export { gitPullCurrent, pm2RestartSporttery, pm2RestartPinnacle, releaseWeb };
export default { gitPullCurrent, pm2RestartSporttery, pm2RestartPinnacle, releaseWeb };
