"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getFileContent = exports.getDirectoryContent = exports.getBranches = exports.getRepositories = exports.removeToken = exports.createToken = exports.getVcsTokensAvailability = void 0;
const utils_1 = require("../utils");
const vcs_1 = require("../components/vcs");
const sendApiError_1 = require("../utils/sendApiError");
const COOKIE_OPTIONS = {
    httpOnly: true,
    secure: true,
    sameSite: 'strict',
    maxAge: 1000 * 60 * 60 * 24 * 365,
};
const ERROR_MESSAGE = {
    VCS_CONFIG_NOT_FOUND: 'vcsSettings is not found in UISettings',
    VCS_ID_REQUIRED: 'vcsId is required',
    VCS_NOT_SUPPORTED: 'The current vcsId is missing from the vcsSettings setting in UISettings',
    TOKEN_REQUIRED: 'Token is required',
    TOKENS_ERROR: 'Error getting vcs tokens availability',
    PATH_REQUIRED: 'Path is required',
    BRANCH_REQUIRED: 'Branch is required',
    REPOSITORY_REQUIRED: 'Repository is required',
    UNAUTHORIZED: 'The service cannot authorize you. Check the token. You can add new token in the section Settings -> VCS',
};
const VCS_COOKIE_PREFIX = 'vcs_token_';
const cookieNameByVcsId = (vcsId) => {
    if (!vcsId)
        throw new utils_1.ErrorWithCode(400, ERROR_MESSAGE.VCS_ID_REQUIRED);
    return VCS_COOKIE_PREFIX + vcsId;
};
const getVcsTokensAvailability = (req, res) => {
    const { cookies } = req;
    try {
        const config = vcs_1.VcsFactory.getVcsSettings(req);
        if (!config)
            throw new utils_1.ErrorWithCode(404, ERROR_MESSAGE.TOKENS_ERROR);
        const vcsTokenKeys = Object.keys(cookies).filter((name) => name.startsWith(VCS_COOKIE_PREFIX));
        const ids = config.reduce((acc, { id }) => {
            if (vcsTokenKeys.includes(VCS_COOKIE_PREFIX + id)) {
                acc.push(id);
            }
            return acc;
        }, []);
        res.status(200).json({ ids });
    }
    catch (e) {
        req.ctx.logError(ERROR_MESSAGE.TOKENS_ERROR, e);
        (0, sendApiError_1.sendApiError)(res, e);
    }
};
exports.getVcsTokensAvailability = getVcsTokensAvailability;
const createToken = (req, res) => {
    const { vcsId, token } = req.body;
    try {
        if (!token)
            throw new utils_1.ErrorWithCode(400, ERROR_MESSAGE.TOKEN_REQUIRED);
        const vcs = vcs_1.VcsFactory.getVcsSettingById(req, vcsId);
        res.cookie(cookieNameByVcsId(vcs.id), token, COOKIE_OPTIONS);
        res.status(200).json({ message: `${cookieNameByVcsId(vcs.id)} token created` });
    }
    catch (e) {
        req.ctx.logError('Error create token', e);
        (0, sendApiError_1.sendApiError)(res, e);
    }
};
exports.createToken = createToken;
const removeToken = (req, res) => {
    const { vcsId } = req.body;
    try {
        res.clearCookie(cookieNameByVcsId(vcsId));
        res.status(200).json({ success: true });
    }
    catch (e) {
        req.ctx.logError('Error remove token', e);
        (0, sendApiError_1.sendApiError)(res, e);
    }
};
exports.removeToken = removeToken;
const getRepositories = async (req, res) => {
    const cookies = req.cookies;
    const vcsId = req.query.vcsId;
    try {
        const token = cookies[cookieNameByVcsId(vcsId)];
        const vcs = vcs_1.VcsFactory.getVcsSettingById(req, vcsId);
        const api = vcs_1.VcsFactory.createVcs(vcs, token);
        const response = await api.getRepositories({ req, res });
        res.status(200).json(response);
    }
    catch (e) {
        req.ctx.logError('Error getting list of repositories', e);
        (0, sendApiError_1.sendApiError)(res, e);
    }
};
exports.getRepositories = getRepositories;
const getBranches = async (req, res) => {
    const cookies = req.cookies;
    const repository = req.query.repository;
    try {
        if (!repository)
            throw new utils_1.ErrorWithCode(400, ERROR_MESSAGE.REPOSITORY_REQUIRED);
        const token = cookies[cookieNameByVcsId(repository.vcsId)];
        const vcs = vcs_1.VcsFactory.getVcsSettingById(req, repository.vcsId);
        const api = vcs_1.VcsFactory.createVcs(vcs, token);
        const response = await api.getBranches({
            repository,
            requests: { req, res },
        });
        res.status(200).json(response);
    }
    catch (e) {
        req.ctx.logError('Error getting list of branches', e);
        (0, sendApiError_1.sendApiError)(res, e);
    }
};
exports.getBranches = getBranches;
const getDirectoryContent = async (req, res) => {
    const cookies = req.cookies;
    const repository = req.query.repository;
    const path = req.query.path;
    const branch = req.query.branch;
    try {
        if (path === undefined)
            throw new utils_1.ErrorWithCode(400, ERROR_MESSAGE.PATH_REQUIRED);
        if (!repository)
            throw new utils_1.ErrorWithCode(400, ERROR_MESSAGE.REPOSITORY_REQUIRED);
        if (!branch)
            throw new utils_1.ErrorWithCode(400, ERROR_MESSAGE.BRANCH_REQUIRED);
        const token = cookies[cookieNameByVcsId(repository.vcsId)];
        const vcs = vcs_1.VcsFactory.getVcsSettingById(req, repository.vcsId);
        const api = vcs_1.VcsFactory.createVcs(vcs, token);
        const response = await api.getRepositoryContent({
            repository,
            branch,
            path,
            requests: {
                req,
                res,
            },
        });
        response.sort((a, b) => {
            if (a.type === 'dir' && b.type === 'file')
                return -1;
            if (a.type === 'file' && b.type === 'dir')
                return 1;
            return a.name.localeCompare(b.name, undefined, { sensitivity: 'base' });
        });
        res.status(200).json(response);
    }
    catch (e) {
        req.ctx.logError('Error getting list of directories', e);
        (0, sendApiError_1.sendApiError)(res, e);
    }
};
exports.getDirectoryContent = getDirectoryContent;
const getFileContent = async (req, res) => {
    const cookies = req.cookies;
    const repository = req.query.repository;
    const path = req.query.path;
    const branch = req.query.branch;
    try {
        if (!path)
            throw new utils_1.ErrorWithCode(400, ERROR_MESSAGE.PATH_REQUIRED);
        if (!repository)
            throw new utils_1.ErrorWithCode(400, ERROR_MESSAGE.REPOSITORY_REQUIRED);
        if (!branch)
            throw new utils_1.ErrorWithCode(400, ERROR_MESSAGE.BRANCH_REQUIRED);
        const token = cookies[cookieNameByVcsId(repository.vcsId)];
        const vcs = vcs_1.VcsFactory.getVcsSettingById(req, repository.vcsId);
        const api = vcs_1.VcsFactory.createVcs(vcs, token);
        const file = await api.getFileContent({
            repository,
            branch,
            path,
            requests: {
                req,
                res,
            },
        });
        res.set('content-type', 'text/json');
        res.set('Content-Disposition', `attachment; filename=${path}`);
        res.status(200).send({ file });
    }
    catch (e) {
        req.ctx.logError('Error getting file content', e);
        (0, sendApiError_1.sendApiError)(res, e);
    }
};
exports.getFileContent = getFileContent;
