import fs from "fs";
import dotenv, {DotenvParseOutput} from "dotenv";
import * as logger from "./src/electron/logger";
import path from "path";
import {MSEMediaPlayerConnection} from "@solid/types/player";
import os from "os";

export type ENV = NodeJS.ProcessEnv | {
  ELECTRON_ENABLE_LOGGING: "true" | "false",
  START_URL: string,
  DATA_DIR: string,
  API_USER: string
  API_PASS: string
  API_GRAPHQL_CODEGEN: string,
  API_BACKEND: string,
  API_GRAPHQL: string,
  API_MINIDUMP: string,
  CREDENTIALS: "same-origin",
  NODE_ENV: "development" | "production",
  PLAYER: "mse" | "native",
  PLAYER_CONNECTION: MSEMediaPlayerConnection,
  PLAYER_LOG: "INFO" | "DEBUG",
  PLAYER_DEFAULT_SPEED: string,
  THEME: "purple",
  BUILD_TARGET: "browser" | "electron"
};

export const ENVDefault: ENV = {
  ELECTRON_ENABLE_LOGGING: "true",
  START_URL: "",
  DATA_DIR: path.join(os.tmpdir(), "solid_storage"),
  API_USER: "",
  API_PASS: "",
  API_GRAPHQL_CODEGEN: "",
  API_BACKEND: "",
  API_GRAPHQL: "/api/graphql",
  API_MINIDUMP: "",
  CREDENTIALS: "same-origin",
  NODE_ENV: "development",
  PLAYER: "native",
  PLAYER_CONNECTION: "auto",
  PLAYER_LOG: "INFO",
  PLAYER_DEFAULT_SPEED: "1",
  THEME: "purple",
  BUILD_TARGET: "electron"
};

declare global {
  interface Process {
    ENV: ENV
  }
}

export function loadENV() {
  try {
    loadDefaultEnv();
    load(".env");
  }
  catch (e) {
    console.error(e);
  }
}

export function loadDefaultEnv() {
  for (const key in ENVDefault) {
    if (!(key in process.env)) {
      process.env[key] = ENVDefault[key];
    }
  }
}

export function load(envFile: string): DotenvParseOutput | undefined {
  try {
    if (!fs.existsSync(envFile)) {
      logger.error(`environment file '${envFile}' is not found.`);
    }

    const envConfig = dotenv.parse(fs.readFileSync(envFile));
    for (const key in envConfig) {
      process.env[key] = envConfig[key];
    }

    console.log("environment loaded from", envFile);
    console.table(envConfig);

    return envConfig;
  }
  catch (e: any) {
    console.warn(e.message);
  }

  return undefined;
}
