import GitlabVisibility from '../shared/types/Gitlab/GitlabVisibility';
import path             from 'path';
import fs               from 'fs';
import { Exercise }     from '../types/DatabaseTypes';
import JSON5            from 'json5';


type ConfigGitlabBadge = { link: string, imageUrl: string }


class Config {
    public readonly api: {
        port: number
    };

    public readonly requestClientValidation: { version: { [client: string]: string } }; // { version: { CLIENT: CONDITION } }

    public readonly jwtConfig: {
        secret: string; expiresIn: number;
    };

    public readonly login: {
        gitlab: {
            client: {
                secret: string
            }
        }
    };

    public readonly gitlab: {
        urls: Array<string>; account: { id: number; username: string; token: string; }; group: { root: number; templates: number; assignments: number; exercises: number; }, badges: { pipeline: ConfigGitlabBadge }
    };

    public readonly assignment: {
        default: { description: string; initReadme: boolean; sharedRunnersEnabled: boolean; visibility: string; wikiEnabled: boolean; template: string }; baseFiles: Array<string>; filename: string
    };

    public readonly exercise: {
        maxSameName: number; resultsFolder: string, pipelineResultsFolder: string; default: { description: string; visibility: string; };
    };

    constructor() {
        this.api = {
            port: Number(process.env.API_PORT || 30992)
        };

        this.requestClientValidation = JSON5.parse(process.env.REQUEST_CLIENT_VALIDATION || '{"version": {}}');

        this.jwtConfig = {
            secret   : process.env.JWT_SECRET_KEY || '',
            expiresIn: Number(process.env.SESSION_TIMEOUT || 0)
        };

        this.login = {
            gitlab: {
                client: {
                    secret: process.env.LOGIN_GITLAB_CLIENT_SECRET || ''
                }
            }
        };

        this.gitlab = {
            urls   : JSON5.parse(process.env.GITLAB_URLS || '[]'),
            account: {
                id      : Number(process.env.GITLAB_DOJO_ACCOUNT_ID || 0),
                username: process.env.GITLAB_DOJO_ACCOUNT_USERNAME || '',
                token   : process.env.GITLAB_DOJO_ACCOUNT_TOKEN || ''
            },
            group  : {
                root       : Number(process.env.GITLAB_GROUP_ROOT_ID || 0),
                templates  : Number(process.env.GITLAB_GROUP_TEMPLATES_ID || 0),
                assignments: Number(process.env.GITLAB_GROUP_ASSIGNMENTS_ID || 0),
                exercises  : Number(process.env.GITLAB_GROUP_EXERCISES_ID || 0)
            },
            badges : {
                pipeline: {
                    link    : process.env.GITLAB_BADGE_PIPELINE_LINK || '',
                    imageUrl: process.env.GITLAB_BADGE_PIPELINE_IMAGE_URL || ''
                }
            }
        };

        this.assignment = {
            default  : {
                description         : process.env.ASSIGNMENT_DEFAULT_DESCRIPTION?.convertWithEnvVars() ?? '',
                initReadme          : process.env.ASSIGNMENT_DEFAULT_INIT_README?.toBoolean() ?? false,
                sharedRunnersEnabled: process.env.ASSIGNMENT_DEFAULT_SHARED_RUNNERS_ENABLED?.toBoolean() ?? true,
                visibility          : process.env.ASSIGNMENT_DEFAULT_VISIBILITY || GitlabVisibility.PRIVATE,
                wikiEnabled         : process.env.ASSIGNMENT_DEFAULT_WIKI_ENABLED?.toBoolean() ?? false,
                template            : process.env.ASSIGNMENT_DEFAULT_TEMPLATE?.replace('{{USERNAME}}', this.gitlab.account.username).replace('{{TOKEN}}', this.gitlab.account.token) ?? ''
            },
            baseFiles: JSON5.parse(process.env.ASSIGNMENT_BASE_FILES || '[]'),
            filename : process.env.ASSIGNMENT_FILENAME || ''
        };

        this.exercise = {
            maxSameName          : Number(process.env.EXERCISE_MAX_SAME_NAME || 0),
            resultsFolder        : process.env.EXERCISE_RESULTS_FOLDER?.convertWithEnvVars() ?? '',
            pipelineResultsFolder: process.env.EXERCISE_PIPELINE_RESULTS_FOLDER ?? '', //Do not use convertWithEnvVars() because it is used in the exercise creation and muste be interpreted at exercise runtime
            default              : {
                description: process.env.EXERCISE_DEFAULT_DESCRIPTION?.convertWithEnvVars() ?? '',
                visibility : process.env.EXERCISE_DEFAULT_VISIBILITY || GitlabVisibility.PRIVATE
            }
        };
    }

    public getResultsFolder(exercise: Exercise): string {
        const folderPath = path.join(this.exercise.resultsFolder, exercise.assignmentName, exercise.id);

        fs.mkdirSync(folderPath, { recursive: true });

        return folderPath;
    }
}


export default new Config();