"use strict";
// *****************************************************************************
// Copyright (C) 2017 TypeFox and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
// *****************************************************************************
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_uri_1 = require("vscode-uri");
const path_1 = require("./path");
class URI {
    constructor(uri = '') {
        if (uri instanceof vscode_uri_1.URI) {
            this.codeUri = uri;
        }
        else {
            this.codeUri = vscode_uri_1.URI.parse(uri);
        }
    }
    /**
     * TODO move implementation to `DefaultUriLabelProviderContribution.getName`
     *
     * @deprecated use `LabelProvider.getName` instead
     */
    get displayName() {
        const base = this.path.base;
        if (base) {
            return base;
        }
        if (this.path.isRoot) {
            return this.path.toString();
        }
        return '';
    }
    /**
     * Return all uri from the current to the top most.
     */
    get allLocations() {
        const locations = [];
        let location = this;
        while (!location.path.isRoot && location.path.hasDir) {
            locations.push(location);
            location = location.parent;
        }
        locations.push(location);
        return locations;
    }
    get parent() {
        if (this.path.isRoot) {
            return this;
        }
        return this.withPath(this.path.dir);
    }
    relative(uri) {
        if (this.authority !== uri.authority || this.scheme !== uri.scheme) {
            return undefined;
        }
        return this.path.relative(uri.path);
    }
    resolve(path) {
        return this.withPath(this.path.join(path.toString()));
    }
    /**
     * @returns a new, absolute URI if one can be computed from the path segments passed in.
     */
    resolveToAbsolute(...pathSegments) {
        const absolutePath = this.path.resolve(...pathSegments.map(path => path.toString()));
        if (absolutePath) {
            return this.withPath(absolutePath);
        }
    }
    /**
     * return a new URI replacing the current with the given scheme
     */
    withScheme(scheme) {
        const newCodeUri = vscode_uri_1.URI.from(Object.assign(Object.assign({}, this.codeUri.toJSON()), { scheme }));
        return new URI(newCodeUri);
    }
    /**
     * return a new URI replacing the current with the given authority
     */
    withAuthority(authority) {
        const newCodeUri = vscode_uri_1.URI.from(Object.assign(Object.assign({}, this.codeUri.toJSON()), { scheme: this.codeUri.scheme, authority }));
        return new URI(newCodeUri);
    }
    /**
     * return this URI without a authority
     */
    withoutAuthority() {
        return this.withAuthority('');
    }
    /**
     * return a new URI replacing the current with the given path
     */
    withPath(path) {
        const newCodeUri = vscode_uri_1.URI.from(Object.assign(Object.assign({}, this.codeUri.toJSON()), { scheme: this.codeUri.scheme, path: path.toString() }));
        return new URI(newCodeUri);
    }
    /**
     * return this URI without a path
     */
    withoutPath() {
        return this.withPath('');
    }
    /**
     * return a new URI replacing the current with the given query
     */
    withQuery(query) {
        const newCodeUri = vscode_uri_1.URI.from(Object.assign(Object.assign({}, this.codeUri.toJSON()), { scheme: this.codeUri.scheme, query }));
        return new URI(newCodeUri);
    }
    /**
     * return this URI without a query
     */
    withoutQuery() {
        return this.withQuery('');
    }
    /**
     * return a new URI replacing the current with the given fragment
     */
    withFragment(fragment) {
        const newCodeUri = vscode_uri_1.URI.from(Object.assign(Object.assign({}, this.codeUri.toJSON()), { scheme: this.codeUri.scheme, fragment }));
        return new URI(newCodeUri);
    }
    /**
     * return this URI without a fragment
     */
    withoutFragment() {
        return this.withFragment('');
    }
    /**
     * return a new URI replacing the current with its normalized path, resolving '..' and '.' segments
     */
    normalizePath() {
        return this.withPath(this.path.normalize());
    }
    get scheme() {
        return this.codeUri.scheme;
    }
    get authority() {
        return this.codeUri.authority;
    }
    get path() {
        if (this._path === undefined) {
            this._path = new path_1.Path(this.codeUri.path);
        }
        return this._path;
    }
    get query() {
        return this.codeUri.query;
    }
    get fragment() {
        return this.codeUri.fragment;
    }
    toString(skipEncoding) {
        return this.codeUri.toString(skipEncoding);
    }
    isEqual(uri, caseSensitive = true) {
        if (!this.hasSameOrigin(uri)) {
            return false;
        }
        return caseSensitive
            ? this.toString() === uri.toString()
            : this.toString().toLowerCase() === uri.toString().toLowerCase();
    }
    isEqualOrParent(uri, caseSensitive = true) {
        if (!this.hasSameOrigin(uri)) {
            return false;
        }
        let left = this.path;
        let right = uri.path;
        if (!caseSensitive) {
            left = new path_1.Path(left.toString().toLowerCase());
            right = new path_1.Path(right.toString().toLowerCase());
        }
        return left.isEqualOrParent(right);
    }
    static getDistinctParents(uris) {
        const result = [];
        uris.forEach((uri, i) => {
            if (!uris.some((otherUri, index) => index !== i && otherUri.isEqualOrParent(uri))) {
                result.push(uri);
            }
        });
        return result;
    }
    hasSameOrigin(uri) {
        return (this.authority === uri.authority) && (this.scheme === uri.scheme);
    }
}
exports.default = URI;
//# sourceMappingURL=uri.js.map