import 'fs';
import { readFile, writeFile } from 'fs/promises';
import { join } from 'path';
import { z } from 'zod';

const getPassphraseEnvName = ({ stage }) => `GITENVS_PASSPHRASE_${stage?.toUpperCase()}`;
const GITENVS_STAGE_ENV_NAME = "GITENVS_STAGE";
const GITENVS_DIR_ENV_NAME = "GITENVS_DIR";

const getCwd = () => {
  const cwd = process.env[GITENVS_DIR_ENV_NAME] ?? process.cwd();
  return cwd;
};

const EnvVarValue = z.object({
  value: z.string(),
  encrypted: z.boolean(),
  isFunction: z.boolean().optional()
});
const EnvVar = z.object({
  id: z.string(),
  fileIds: z.array(z.string()),
  key: z.string(),
  values: z.record(z.string(), EnvVarValue)
});
const EnvFileType = z.enum(["dotenv", ".ts"]);
const EnvFile = z.object({
  id: z.string(),
  name: z.string(),
  filePath: z.string(),
  type: EnvFileType
});
const EnvStage = z.object({
  name: z.string(),
  publicKey: z.string(),
  encryptedPrivateKey: z.string()
});
const Gitenvs = z.object({
  version: z.enum(["2"]),
  envStages: z.array(EnvStage),
  envFiles: z.array(EnvFile),
  envVars: z.array(EnvVar)
});
const Gitenvs1 = z.object({
  version: z.enum(["1"]),
  envStages: z.array(EnvStage),
  envFiles: z.array(EnvFile),
  envVars: z.array(
    z.object({
      id: z.string(),
      fileId: z.string(),
      key: z.string(),
      values: z.record(z.string(), EnvVarValue)
    })
  )
});
z.object({
  stageName: z.string(),
  passphrase: z.string()
});

const latestGitenvsVersion = 2;
const getIsLatestGitenvsVersion = async () => {
  return await getGitenvsVersion() === latestGitenvsVersion;
};
const getGitenvsVersion = async () => {
  const gitenvsContent = await readFile(join(getCwd(), "gitenvs.json"), "utf-8");
  const gitenvs = z.object({ version: z.string() }).parse(JSON.parse(gitenvsContent));
  return parseInt(gitenvs.version);
};
const getGitenvs = async () => {
  const gitenvsContent = await readFile(join(getCwd(), "gitenvs.json"), "utf-8");
  const gitenvs = Gitenvs.parse(JSON.parse(gitenvsContent));
  return gitenvs;
};
const saveGitenvs = async (gitenvs) => {
  const path = join(getCwd(), "gitenvs.json");
  await writeFile(path, JSON.stringify(gitenvs, null, 2));
};

export { Gitenvs1 as G, getCwd as a, getPassphraseEnvName as b, getGitenvsVersion as c, getIsLatestGitenvsVersion as d, GITENVS_STAGE_ENV_NAME as e, getGitenvs as g, latestGitenvsVersion as l, saveGitenvs as s };
