import { assert } from "../../core/assert.js";

const rx_url_schema = /[a-zA-Z0-9_\-]+\:\/\//;

/**
 *
 * @param {string} path
 * @return {boolean}
 */
function isGlobalPath(path) {
    //search for URL schema at the start of the path
    return path.search(rx_url_schema) === 0;
}

// *** Environment setup code ***
const ENVIRONMENT_IS_WEB = typeof window === 'object';
const ENVIRONMENT_IS_NODE = typeof process === 'object' && !ENVIRONMENT_IS_WEB;
const ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
const ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;

/**
 *
 * @param {string} path
 * @return {string}
 */
function localPathToGlobal(path) {
    /**
     * @type {Window|DedicatedWorkerGlobalScope}
     */
    let scope;

    if (ENVIRONMENT_IS_WEB) {
        scope = window;
    } else if (ENVIRONMENT_IS_WORKER) {
        scope = self;
    } else if (ENVIRONMENT_IS_NODE) {

        let normalized_path = `${process.cwd()}/`.replace(/\\/g, '/');

        // remove multiple sequential slashes
        normalized_path = normalized_path.replace(/\/+/g, '/');

        if (normalized_path[0] !== '/') {
            // Windows drive letter must be prefixed with a slash.
            normalized_path = `/${normalized_path}`;
        }

        scope = {
            location: {
                pathname: normalized_path,
                host: '',
                protocol: 'file:'
            }
        };
    } else {
        throw new Error('Unknown environment');
    }

    const location = scope.location;
    const pathname = location.pathname;

    let directoryPath;

    /*
    path name contains file name also, there are two options here, "a/b" or "a/b/" second is a directory
    we need to extract directory to load relative path
    */

    if (pathname.endsWith('/')) {
        //path is to a directory, strip last slash
        directoryPath = pathname.substring(0, pathname.length - 1);
    } else {
        //path is to a file
        const i = pathname.lastIndexOf('/');

        if (i === -1) {
            //root level file
            directoryPath = ""
        } else {
            directoryPath = pathname.substring(0, i);
        }
    }

    const urlBase = location.protocol + "//" + location.host + directoryPath + "/";
    return urlBase + path;
}

/**
 * Given a path, which may be a local path, produce a fully qualified URL
 * @example '/path' -> 'http://example.com/path'
 * @example 'some/local/path' -> 'http://example.com/current_path/some/local/path'
 * @param {string} path
 * @return {string}
 */
export function convertPathToURL(path) {
    assert.isString(path, 'path');

    const is_global = isGlobalPath(path);

    let result = path;

    if (!is_global) {
        result = localPathToGlobal(path);
    }

    return result;
}
