import { trainCase } from "case-anything";
import { execSync } from "child_process";
import { promises as fs } from "fs";
import { tmpdir } from "os";
import { join } from "path";
import util from "util";
const exec = util.promisify(require("child_process").exec);

import { uuid } from "uuidv4";

function throwIfError(error) {
  if (error != undefined) {
    console.error(`error: ${error.message}`);
  }
}

export async function cloneRepo(httpAddr: string) {
  const tmpFolderPath = await fs.mkdtemp(join(tmpdir(), "dt-"));
  console.log(`Cloning repo to directory: ${tmpFolderPath}`);

  try {
    const stdOut = execSync(
      `git clone ${httpAddr} ${tmpFolderPath}`
    ).toString();
    console.log(`Clone output is: ${stdOut}`);
  } catch (error) {
    console.error(
      `Failed to clone repo: ${error.status} ${
        error.message
      } ${error.stderr.toString()} ${error.stdout.toString()}`
    );
    throw error.message;
  }

  return tmpFolderPath;
}

export async function pushRepo(repoPath: string) {
  try {
    const stdOut = execSync(`git -C  ${repoPath} push`).toString();
    console.log(`Push output is: ${stdOut}`);
  } catch (error) {
    console.error(
      `Failed to push to repo: ${error.status} 
      ${error.message} 
      ${error.stderr.toString()} 
      ${error.stdout.toString()}`
    );
    throw error.message;
  }

  return repoPath;
}

export async function commitRepo(repoPath) {
  try {
    const stdOut = execSync(
      `git -C ${repoPath} add . && git -C ${repoPath} commit -m \'event commit\'`
    );
    console.log(`Commit output is: ${stdOut}`);
  } catch (error) {
    console.error(
      `Failed to commit to repo: ${error.status} 
      ${error.message} 
      ${error.stderr.toString()} 
      ${error.stdout.toString()}`
    );
    throw error.message;
  }
  return repoPath;
}

export async function createAndPublishNewBranch(
  repoPath: string,
  branchPrefix: string
) {
  try {
    // timestamp
    const branchName = trainCase(branchPrefix) + "-" + Date.now();
    execSync(
      `git -C ${repoPath} checkout -b ${branchName} && git -C ${repoPath} push -u origin --set-upstream ${branchName}`
    );
    return branchName;
  } catch (error) {
    console.error(
      `Failed to push to repo: ${error.status} 
      ${error.message} 
      ${error.stderr.toString()} 
      ${error.stdout.toString()}`
    );
    throw error.message;
  }
}

export async function removeRepo(repoPath) {
  try {
    execSync(`rm -r ${repoPath}`);
  } catch (error) {
    `Failed to push to repo: ${error.status} 
    ${error.message} 
    ${error.stderr.toString()} 
    ${error.stdout.toString()}`;

    throw error.message;
  }
}
