"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.GithubApi = void 0;
const axios_1 = __importDefault(require("axios"));
const utils_1 = require("../../utils");
class GithubApi {
    constructor({ token, baseUrl, vcsId, maxFileSize, }) {
        if (!token)
            throw new utils_1.ErrorWithCode(400, 'Token is required');
        this.token = token;
        this.baseUrl = baseUrl;
        this.vcsId = vcsId;
        this.maxFileSize = maxFileSize;
    }
    getProjectId(repository) {
        return `${repository.owner}/${repository.name}`;
    }
    getRequestHeaders() {
        return {
            Authorization: `token ${this.token}`,
        };
    }
    getRepositories() {
        return axios_1.default
            .get(`${this.baseUrl}/user/repos`, {
            headers: this.getRequestHeaders(),
        })
            .then((response) => {
            return response.data.reduce((acc, repositoryData) => {
                acc[repositoryData.name] = {
                    name: repositoryData.name,
                    owner: repositoryData.owner.login,
                    defaultBranch: repositoryData.default_branch,
                    vcsId: this.vcsId,
                };
                return acc;
            }, {});
        });
    }
    getBranches({ repository }) {
        return axios_1.default
            .get(`${this.baseUrl}/repos/${this.getProjectId(repository)}/branches`, {
            headers: this.getRequestHeaders(),
        })
            .then((response) => {
            return response.data.map((i) => i.name);
        });
    }
    getRepositoryContent({ repository, branch, path = '', }) {
        return axios_1.default
            .get(`${this.baseUrl}/repos/${this.getProjectId(repository)}/contents/${path}`, {
            headers: this.getRequestHeaders(),
            params: {
                ref: branch,
            },
        })
            .then((response) => {
            return response.data.map((item) => {
                return {
                    name: item.name,
                    type: item.type,
                    url: item.html_url,
                };
            });
        });
    }
    async getFileContent({ repository, path, branch, }) {
        const response = await axios_1.default.get(`${this.baseUrl}/repos/${this.getProjectId(repository)}/contents/${path}`, {
            headers: this.getRequestHeaders(),
            params: {
                ref: branch,
            },
            responseType: 'stream',
        });
        const fileStream = response.data;
        const streamData = await new Promise((resolve, reject) => {
            let temp = '';
            fileStream.on('data', (chunk) => {
                temp += chunk.toString();
                if (Buffer.byteLength(temp) > this.maxFileSize)
                    reject(new Error(`File is too big. Max size ${this.maxFileSize}Mb`));
            });
            fileStream.on('end', () => {
                resolve(temp);
            });
            fileStream.on('error', (err) => {
                reject(err);
            });
        });
        return Buffer.from(JSON.parse(streamData).content, 'base64').toString();
    }
}
exports.GithubApi = GithubApi;
