import { findByKnownFilenames } from "./findByKnownFilenames.js";
import { findByRobots } from "./findByRobots.js";

/**
 * Find sitemap URL by different methods.
 *
 * @param rootUrl The root URL of your current website (with leading `/`!)
 * @param forceSitemapArgument See `findByRobots`
 * @param tryKnownFilenames See `findByKnownFilenames`
 * @param filterSitemap See `findByRobots`
 */
function findSitemap(
    rootUrl: string,
    forceSitemapArgument?: string,
    tryKnownFilenames?: string[],
    filterSitemap?: string,
) {
    return new Promise<string[] | false>((resolve, reject) => {
        /**
         * We need to wrap the resolving mechanism in an additional non-blocking `setTimeout`.
         * Why? Requesting a lot of wrong URLs with `findByKnownFilenames` could lead to a race
         * condition within browsers and their Race Cache With Network (RCWN).
         *
         * Without this, this could lead to wrong error messages when requesting the found sitemap URL
         * again, e.g. with `crawl`.
         */
        const resolver = (result: string[] | false) => setTimeout(() => resolve(result), 100);

        (async () => {
            try {
                // 1. `robots.txt`
                const robotsTxt = await findByRobots(rootUrl, undefined, filterSitemap);
                if (robotsTxt) {
                    resolver(robotsTxt);
                    return;
                }

                // 2. Known filenames
                const byKnownFilenames = await findByKnownFilenames(rootUrl);
                if (byKnownFilenames) {
                    resolver([byKnownFilenames]);
                    return;
                }

                // 3. Force and activate `robots.txt` and sitemaps in WordPress itself
                // e.g. when the setting of visibility is activated in Settings > Reading
                // 1. `robots.txt`
                if (forceSitemapArgument) {
                    const robotsTxtForce = await findByRobots(rootUrl, forceSitemapArgument, filterSitemap);
                    if (robotsTxtForce) {
                        resolver(robotsTxtForce);
                        return;
                    }
                }

                // 4. Try another set of known filenames
                if (tryKnownFilenames) {
                    const byKnownFilenamesCustom = await findByKnownFilenames(rootUrl, tryKnownFilenames);
                    if (byKnownFilenamesCustom) {
                        resolver([byKnownFilenamesCustom]);
                        return;
                    }
                }

                resolver(false);
            } catch (e) {
                reject(e);
            }
        })();
    });
}

export { findSitemap };
