/*---------------------------------------------------------
 * Copyright (C) Microsoft Corporation. All rights reserved.
 *--------------------------------------------------------*/
"use strict";
const basePathTransformer_1 = require("./basePathTransformer");
const utils = require("../utils");
const vscode_debugadapter_1 = require("vscode-debugadapter");
const ChromeUtils = require("../chrome/chromeUtils");
const chromeDebugAdapter_1 = require("../chrome/chromeDebugAdapter");
const path = require("path");
/**
 * Converts a local path from Code to a path on the target.
 */
class UrlPathTransformer extends basePathTransformer_1.BasePathTransformer {
    constructor() {
        super(...arguments);
        this._pathMapping = {};
        this._clientPathToTargetUrl = new Map();
        this._targetUrlToClientPath = new Map();
    }
    launch(args) {
        this._webRoot = args.webRoot;
        this._pathMapping = args.pathMapping || {};
        return super.launch(args);
    }
    attach(args) {
        this._webRoot = args.webRoot;
        this._pathMapping = args.pathMapping || {};
        return super.attach(args);
    }
    setBreakpoints(args) {
        if (!args.source.path) {
            // sourceReference script, nothing to do
            return;
        }
        if (utils.isURL(args.source.path)) {
            // already a url, use as-is
            vscode_debugadapter_1.logger.log(`Paths.setBP: ${args.source.path} is already a URL`);
            return;
        }
        const path = utils.canonicalizeUrl(args.source.path);
        const url = this.getTargetPathFromClientPath(path);
        if (url) {
            args.source.path = url;
            vscode_debugadapter_1.logger.log(`Paths.setBP: Resolved ${path} to ${args.source.path}`);
            return;
        }
        else {
            vscode_debugadapter_1.logger.log(`Paths.setBP: No target url cached yet for client path: ${path}.`);
            args.source.path = path;
            return;
        }
    }
    clearTargetContext() {
        this._clientPathToTargetUrl = new Map();
        this._targetUrlToClientPath = new Map();
    }
    scriptParsed(scriptUrl) {
        let clientPath = ChromeUtils.targetUrlToClientPathByPathMappings(scriptUrl, this._pathMapping);
        if (!clientPath) {
            clientPath = ChromeUtils.targetUrlToClientPath(this._webRoot, scriptUrl);
        }
        if (!clientPath) {
            // It's expected that eval scripts (eval://) won't be resolved
            if (!scriptUrl.startsWith(chromeDebugAdapter_1.ChromeDebugAdapter.EVAL_NAME_PREFIX)) {
                vscode_debugadapter_1.logger.log(`Paths.scriptParsed: could not resolve ${scriptUrl} to a file under webRoot: ${this._webRoot}. It may be external or served directly from the server's memory (and that's OK).`);
            }
        }
        else {
            vscode_debugadapter_1.logger.log(`Paths.scriptParsed: resolved ${scriptUrl} to ${clientPath}. webRoot: ${this._webRoot}`);
            this._clientPathToTargetUrl.set(clientPath, scriptUrl);
            this._targetUrlToClientPath.set(scriptUrl, clientPath);
            scriptUrl = clientPath;
        }
        return scriptUrl;
    }
    stackTraceResponse(response) {
        response.stackFrames.forEach(frame => {
            if (frame.source && frame.source.path) {
                // Try to resolve the url to a path in the workspace. If it's not in the workspace,
                // just use the script.url as-is. It will be resolved or cleared by the SourceMapTransformer.
                const clientPath = this.getClientPathFromTargetPath(frame.source.path) ||
                    ChromeUtils.targetUrlToClientPath(this._webRoot, frame.source.path);
                // Incoming stackFrames have sourceReference and path set. If the path was resolved to a file in the workspace,
                // clear the sourceReference since it's not needed.
                if (clientPath) {
                    frame.source.path = clientPath;
                    frame.source.sourceReference = undefined;
                    frame.source.origin = undefined;
                }
            }
        });
    }
    getTargetPathFromClientPath(clientPath) {
        // If it's already a URL, skip the Map
        return path.isAbsolute(clientPath) ?
            this._clientPathToTargetUrl.get(utils.canonicalizeUrl(clientPath)) :
            clientPath;
    }
    getClientPathFromTargetPath(targetPath) {
        return this._targetUrlToClientPath.get(targetPath);
    }
}
exports.UrlPathTransformer = UrlPathTransformer;

//# sourceMappingURL=urlPathTransformer.js.map
