"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateMeta = exports.supported = exports.guessAdapterFromFileName = exports.isURL = exports.createRemoteStream = void 0;
const tslib_1 = require("tslib");
const fs_1 = tslib_1.__importDefault(require("fs"));
const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
const path_1 = tslib_1.__importDefault(require("path"));
// Method for handing off the parsing of a gff3 file URL.
// Calls the proper parser depending on if it is gzipped or not.
// Returns a @gmod/gff stream.
async function createRemoteStream(urlIn) {
    const response = await (0, node_fetch_1.default)(urlIn);
    if (!response.ok) {
        throw new Error(`Failed to fetch ${urlIn} status ${response.status} ${response.statusText}`);
    }
    return response;
}
exports.createRemoteStream = createRemoteStream;
// Checks if the passed in string is a valid URL.
// Returns a boolean.
function isURL(FileName) {
    let url;
    try {
        url = new URL(FileName);
    }
    catch (_) {
        return false;
    }
    return url.protocol === 'http:' || url.protocol === 'https:';
}
exports.isURL = isURL;
function makeLocation(location, protocol) {
    if (protocol === 'uri') {
        return { uri: location, locationType: 'UriLocation' };
    }
    if (protocol === 'localPath') {
        return {
            localPath: path_1.default.resolve(location),
            locationType: 'LocalPathLocation',
        };
    }
    throw new Error(`invalid protocol ${protocol}`);
}
function guessAdapterFromFileName(filePath) {
    // const uri = isURL(filePath) ? filePath : path.resolve(filePath)
    const protocol = isURL(filePath) ? 'uri' : 'localPath';
    const name = path_1.default.basename(filePath);
    if (/\.vcf\.b?gz$/i.test(filePath)) {
        return {
            trackId: name,
            name: name,
            assemblyNames: [],
            adapter: {
                type: 'VcfTabixAdapter',
                vcfGzLocation: makeLocation(filePath, protocol),
            },
        };
    }
    else if (/\.gff3?\.b?gz$/i.test(filePath)) {
        return {
            trackId: name,
            name,
            assemblyNames: [],
            adapter: {
                type: 'Gff3TabixAdapter',
                gffGzLocation: makeLocation(filePath, protocol),
            },
        };
    }
    else if (/\.gtf?$/i.test(filePath)) {
        return {
            trackId: name,
            name,
            assemblyNames: [],
            adapter: {
                type: 'GtfAdapter',
                gtfLocation: { uri: filePath, locationType: 'UriLocation' },
            },
        };
    }
    else if (/\.vcf$/i.test(filePath)) {
        return {
            trackId: name,
            name,
            assemblyNames: [],
            adapter: {
                type: 'VcfAdapter',
                vcfLocation: makeLocation(filePath, protocol),
            },
        };
    }
    else if (/\.gff3?$/i.test(filePath)) {
        return {
            trackId: name,
            name,
            assemblyNames: [],
            adapter: {
                type: 'Gff3Adapter',
                gffLocation: makeLocation(filePath, protocol),
            },
        };
    }
    else {
        throw new Error(`Unsupported file type ${filePath}`);
    }
}
exports.guessAdapterFromFileName = guessAdapterFromFileName;
function supported(type) {
    return [
        'Gff3TabixAdapter',
        'VcfTabixAdapter',
        'Gff3Adapter',
        'VcfAdapter',
    ].includes(type);
}
exports.supported = supported;
/**
 * Generates metadata of index given a filename (trackId or assembly)
 * @param name -  assembly name or trackId
 * @param attributes -  attributes indexed
 * @param include -  feature types included from index
 * @param exclude -  feature types excluded from index
 * @param configs - list of track
 */
async function generateMeta({ configs, attributes, outDir, name, exclude, assemblyNames, }) {
    const tracks = configs.map(config => {
        const { trackId, textSearching, adapter } = config;
        const includeExclude = (textSearching === null || textSearching === void 0 ? void 0 : textSearching.indexingFeatureTypesToExclude) || exclude;
        const metaAttrs = (textSearching === null || textSearching === void 0 ? void 0 : textSearching.indexingAttributes) || attributes;
        return {
            trackId: trackId,
            attributesIndexed: metaAttrs,
            excludedTypes: includeExclude,
            adapterConf: adapter,
        };
    });
    fs_1.default.writeFileSync(path_1.default.join(outDir, 'trix', `${name}_meta.json`), JSON.stringify({
        dateCreated: new Date().toISOString(),
        tracks,
        assemblyNames,
    }, null, 2));
}
exports.generateMeta = generateMeta;
