const axios = require('axios').default;
const semver = require('semver');
const argv = require('process').argv;

async function obterNumeroPaginas(url, token) {
    const resposta = await axios.get(url, {
        headers: {
            'PRIVATE-TOKEN': token
        }
    });

    return resposta.headers['x-total-pages'];
}

async function listarPorPagina(url, pagina, token) {
    const resposta = await axios.get(`${url}?page=${pagina}`, {
        headers: {
            'PRIVATE-TOKEN': token
        }
    });

    return resposta.data;
}

function ehVersaoDeProducao(versao) {
    return new RegExp(/^\d+\.\d+\.\d+-?/).test(versao);
}

function extrairNumeroDeVersao(versao) {
    const match = versao.match(/^\d+\.\d+\.\d+/);

    return match == null ? "" : match[0];
}

function nuloOuVazio(v) {
    return v === undefined || v === null || v == "";
}

function compararVersoes(v1, v2) {
    return nuloOuVazio(v1) || nuloOuVazio(v2) ? 0 :
        ehVersaoDeProducao(v1) && !ehVersaoDeProducao(v2) ? 1 :
        ehVersaoDeProducao(v2) && !ehVersaoDeProducao(v1) ? -1 :
        ehVersaoDeProducao(v1) && ehVersaoDeProducao(v2) ? (semver.compare(extrairNumeroDeVersao(v1), extrairNumeroDeVersao(v2))) :
        v1.localeCompare(v2);
}

function ordenarListaImagensETags(listaImagensETags) {
    listaImagensETags.sort((elemento1, elemento2) => compararVersoes(elemento1.name, elemento2.name));
    listaImagensETags.reverse();
    return listaImagensETags;
}

function obterListaDeVersoesParaApresentacao(listaImagensETags) {
    return ordenarListaImagensETags(listaImagensETags).map(e => e.name).join("\n");
}

async function main() {
    const token = argv.length >= 3 ? argv[2] : null;

    if (token == null) {
        console.error('token nao informado');
        return;
    }

    const tagsUrl = 'https://gitlab.microuniverso.com.br/api/v4/projects/77/repository/tags';
    const branchesUrl = 'https://gitlab.microuniverso.com.br/api/v4/projects/77/repository/branches';

    const numeroPaginasTags = await obterNumeroPaginas(tagsUrl, token);
    const numeroPaginasBranches = await obterNumeroPaginas(branchesUrl, token);

    const totalPaginasTags = Math.min(numeroPaginasTags, 2);
    const totalPaginasBranches = Math.min(numeroPaginasBranches, 2);

    const promessasTags = [];
    const promessasBranches = [];

    for (let pagina = 1; pagina <= totalPaginasTags; pagina++) {
        promessasTags.push(listarPorPagina(tagsUrl, pagina, token));
    }

    for (let pagina = 1; pagina <= totalPaginasBranches; pagina++) {
        promessasBranches.push(listarPorPagina(branchesUrl, pagina, token));
    }

    const [tags, branches] = await Promise.all([
        Promise.all(promessasTags),
        Promise.all(promessasBranches)
    ]);

    let listaImagensETags = tags.flat();
    let listaBranches = branches.flat();

    // Combinar branches e tags, colocando branches em cima
    const listaFinal = [...listaBranches, ...listaImagensETags];

    return obterListaDeVersoesParaApresentacao(listaFinal);
}

main().then(lista => {
    if (lista != null) {
        console.log(lista);
    }
});
