// 获取所有的本地的vscode-extensions, code --list-extensions --show-versions 命令，返回回来的格式是
// 判断是否有downloads目录，如果没有则创建
// 下载所有的extensions到downloads目录
// 下载链接为 https://marketplace.visualstudio.com/_apis/public/gallery/publishers/${creator}/vsextensions/${name}/${version}/vspackage
import { promisify } from 'util';
import { exec as execCmd } from 'child_process';
import fs from 'fs';
import path from 'path';
import { pipeline as pipe } from 'stream';
import got from 'got';

const pipeline = promisify(pipe);
const exec = promisify(execCmd);

const dest = 'downloads_info';
function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

function getExtInfo(str) {
  const regex = /([^.]+)\.([^@]+)@(.+)/;
  const match = str.match(regex);

  return {
    creator: match[1],
    name: match[2],
    version: match[3],
  };
}

function mkdir(directory) {
  if (!fs.existsSync(directory)) {
    fs.mkdirSync(directory);
    console.log(`已创建 ${directory} 目录`);
  } else {
    console.log(`${directory} 目录已存在`);
  }
}

async function downloadFile({ creator, name, version }, retries = 3) {
  // 下载链接为 https://marketplace.visualstudio.com/_apis/public/gallery/publishers/${creator}/vsextensions/${name}/${version}/vspackage
  const url = `https://marketplace.visualstudio.com/_apis/public/gallery/publishers/${creator}/vsextensions/${name}/${version}/vspackage`;

  const fileName = `${creator}.${name}-${version}.vsix`;
  const filePath = path.join(dest, fileName);

  // 跳过已经下载的文件
  if (fs.existsSync(filePath)) {
    console.log(`文件${fileName}已存在，跳过下载`);
    return;
  }

  // const response = await got.stream(url);
  // const writeStream = fs.createWriteStream(dest);
  // response.pipe(writeStream);
  try {
    await pipeline(got.stream(url), fs.createWriteStream(filePath));
    console.log(`文件${fileName}下载成功`);
  } catch (error) {
    if (error.response && error.response.statusCode === 429) {
      console.log('HTTP 429 错误，将在 5 秒后重试...');
      await sleep(5000);
      if (retries === 0) {
        throw new Error(`下载文件${fileName}时出错:\n下载路径是${url}\n尝试多次下载仍然失败`);
      } else {
        return downloadFile({ creator, name, version }, retries - 1);
      }
    } else {
      throw new Error(`下载文件${fileName}时出错:\n下载路径是${url}\n ${error.message}`);
    }
  }
}

async function main() {
  let arr = [];
  try {
    const { stdout } = await exec('code --list-extensions --show-versions');
    arr = stdout.split('\n').filter((line) => line);
    arr = arr.map((str) => getExtInfo(str));
    // console.log('🚀 ~ file: index1.mjs:16 ~ main ~ arr:', arr);
    mkdir(dest);
    // 下载所有的extensions到downloads_info目录
    // https://marketplace.visualstudio.com/_apis/public/gallery/publishers/formulahendry/vsextensions/auto-close-tag/0.5.14/vspackage
    const promises = [];
    console.log('创建下载任务');
    for (const item of arr) {
      promises.push(downloadFile(item));
    }
    console.log('开始下载');
    await Promise.all(promises);
    const files = await fs.promises.readdir(dest);
    if (files.length === arr.length) {
      console.log('全部下载完成');
    } else {
      console.log('下载失败，请重试');
    }
  } catch (error) {
    console.error(`执行命令时出错: `, error);
  }
}

main();
