import VersionStyle from '../plugin/version';
import {LATEST} from './constant';
import { logger } from './logger';
import Git from 'nodegit';

const sshFlag = 'git@';
const tagFlag = 'refs/tags/';
const gitPrefix = 'http://_mismatch@';

const callbacks = {
  credentials: () => {
    return Git.Cred.userpassPlaintextNew('feflow', 'sn7564SNQ');
  }
}

export async function getVersion(repoUrl: string, version?: string) {
  const url = await transformUrl(repoUrl)
  const remote = await Git.Remote.createDetached(url);
  await remote.connect(Git.Enums.DIRECTION.FETCH, callbacks);
  const referenceList = await remote.referenceList();

  let satisfiedMaxVersion: string | undefined;
  for (const reference of referenceList) {
    const ref = reference.name();
    if (!ref?.startsWith(tagFlag)) {
      continue;
    }
    const tag = ref?.substring(tagFlag.length);
    if (!VersionStyle.check(tag)) {
      continue;
    }
    if (tag === version) {
      return tag;
    }
    if (version && version !== LATEST && !VersionStyle.satisfies(tag, version)) {
      continue;
    }
    if (!satisfiedMaxVersion || VersionStyle.gt(tag, satisfiedMaxVersion)) {
      satisfiedMaxVersion = tag;
    }
  }
  return satisfiedMaxVersion;
}

export async function clone(url: string, tag: string, pkgPath: string) {
  const authUrl = await transformUrl(url)
  const repo = await Git.Repository.init(pkgPath, 0);
  await Git.Remote.createWithFetchspec(
    repo,
    'origin',
    authUrl,
    `+${tagFlag}${tag}:refs/remotes/origin/${tag}`,
  );
  await repo.fetchAll({callbacks});
  const r = await repo.getReference(`${tagFlag}${tag}`);
  const commit = await repo.getCommit(await r.peel(Git.Object.TYPE.COMMIT));
  await Git.Reset.reset(repo, commit, Git.Reset.TYPE.HARD);
}

// 统一将 url 转换为 http://xx@git.woa.com/xx.git 形式
export async function transformUrl(url: string) {
  if (url.startsWith(gitPrefix)) {
    return url;
  }
  logger.debug(`URL转换，转换前：${url}`);
  let transformedUrl = url;
  if (transformedUrl.startsWith(sshFlag)) {
    transformedUrl = transformedUrl.replace(sshFlag, '').replace(':', '/');
  }
  transformedUrl = transformedUrl.replace('https://', '')
    .replace('http://', '')
    .replace('git.code.oa.com', 'git.woa.com');
  // Note: nodegit 可能会被 ~/.gitconfig 里的 insteadOf 影响，导致 url 被替换，随之出现预期外的问题
  // 例如 http 协议 被转换为 ssh 协议，则导致自带的 http 认证失效进入异常逻辑
  // 通过给 url 加料降低这种替换的可能性，其中 _mismatch 只是我随意取的，不影响最终可用性
  transformedUrl = 'http://_mismatch@' + transformedUrl;
  if (!transformedUrl.endsWith('.git')) {
    transformedUrl = transformedUrl + '.git';
  }
  logger.debug(`转换后URL为：${transformedUrl}`);
  return transformedUrl;
}
