'use strict';

const knex = require('./knex');
const whereOr = require('./utils/where-or');
const { fetchSites } = require('./sites');

async function curateNetwork(network, includeParameters = false) {
    const [sites, studios] = await Promise.all([
        fetchSites({ network_id: network.id }),
        knex('studios')
            .where({ network_id: network.id }),
    ]);

    return {
        id: network.id,
        name: network.name,
        url: network.url,
        description: network.description,
        slug: network.slug,
        sites,
        parameters: includeParameters ? network.parameters : null,
        studios: studios.map(studio => ({
            id: studio.id,
            name: studio.name,
            url: studio.url,
            description: studio.description,
            slug: studio.slug,
        })),
    };
}

function curateNetworks(releases) {
    return Promise.all(releases.map(async release => curateNetwork(release)));
}

async function findNetworkByUrl(url) {
    const { hostname } = new URL(url);
    const domain = hostname.replace(/^www./, '');

    const network = await knex('networks')
        .where('networks.url', 'like', `%${domain}`)
        .orWhere('networks.url', url)
        .first();

    if (network) {
        return curateNetwork(network, true);
    }

    return null;
}

async function fetchNetworks(queryObject) {
    const releases = await knex('networks')
        .where(builder => whereOr(queryObject, 'networks', builder))
        .limit(100);

    return curateNetworks(releases);
}

async function fetchNetworksFromReleases() {
    const releases = await knex('releases')
        .select('site_id', '')
        .leftJoin('sites', 'sites.id', 'releases.site_id')
        .leftJoin('networks', 'networks.id', 'sites.network_id')
        .groupBy('networks.id')
        .limit(100);

    return curateNetworks(releases);
}

module.exports = {
    fetchNetworks,
    fetchNetworksFromReleases,
    findNetworkByUrl,
};
