import dotenv from 'dotenv';
import Logger from './logger';

dotenv.config();

function isValidInput(envVariable: string | undefined): boolean {
    if (
        !envVariable ||
        envVariable === undefined ||
        envVariable === 'undefined'
    ) {
        return false;
    }
    return true;
}

class OptionalStringEnvVariable {
    static convertToType(envVariable: string | undefined): string | undefined {
        return envVariable;
    }
}

export class StringEnvVariable {
    static convertToType(envVariable: string | undefined): string {
        if (!isValidInput(envVariable)) {
            throw new Error(envVariable); // throw new Error('test'); // TODO Logger and process.exit
        }

        return envVariable!;
    }
}

class NumberEnvVariable {
    static convertToType(envVariable: string | undefined): number {
        if (!isValidInput(envVariable)) {
            throw new Error(envVariable);
        }

        return parseInt(envVariable!, 10);
    }
}

class BooleanEnvVariable {
    static convertToType(envVariable: string | undefined): boolean {
        if (!isValidInput(envVariable)) {
            throw new Error(envVariable);
        }

        return envVariable === 'true' || envVariable === 'True';
    }
}

export default class EnvVariableHelper {
    private static ENV_FILE = {
        DATABASE_URL: StringEnvVariable,
        BACKEND_HOST: StringEnvVariable,
        BACKEND_PORT: NumberEnvVariable,
        FRONTEND_PROTOCOL: StringEnvVariable,
        FRONTEND_HOST: StringEnvVariable,
        FRONTEND_PORT: NumberEnvVariable,
        ACCESS_TOKEN_SECRET: StringEnvVariable,
        REFRESH_TOKEN_SECRET: StringEnvVariable,
        ADMIN_USER: StringEnvVariable,
        ADMIN_PASSWORD: StringEnvVariable,
        MAIL_SMTP_HOST: StringEnvVariable,
        MAIL_SMTP_PORT: NumberEnvVariable,
        MAIL_SMTP_ENCRYPTED: BooleanEnvVariable,
        MAIL_SMTP_FROM_ADDRESS: StringEnvVariable,
        MAIL_SMTP_OPTIONAL_DKIM_DOMAIN_NAME: OptionalStringEnvVariable,
        MAIL_SMTP_OPTIONAL_DKIM_KEY_SELECTOR: OptionalStringEnvVariable,
        MAIL_SMTP_OPTIONAL_DKIM_CERT_FILE: OptionalStringEnvVariable,
        MAIL_HTML_TEMPLATE_WELCOME_CUSTOMER: StringEnvVariable,
        MAIL_SMTP_AUTH_USER: StringEnvVariable,
        MAIL_SMTP_AUTH_PASSWORD: StringEnvVariable,
    };

    static readonly VARIABLES: {
        [key: string]: any;
    } = {};

    static loadVariables() {
        for (const entry of Object.entries(this.ENV_FILE)) {
            const key: string = entry[0];
            const envVariable = process.env[key];

            const value = entry[1];

            try {
                this.VARIABLES[key] = value.convertToType(envVariable);
            } catch (e) {
                this.handleInvalidOrMissingEnvVariable(key);
            }
        }
    }

    private static handleInvalidOrMissingEnvVariable(variable: string) {
        Logger.sendMessage(
            `Environment variable ${variable} is invalid or missing. Please define it in the .env file. The program is terminated.`
        );
        process.exit(1);
    }
}
EnvVariableHelper.loadVariables();
