// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

Sources.SourceFormatData = class {
  /**
   * @param {!Workspace.UISourceCode} originalSourceCode
   * @param {!Workspace.UISourceCode} formattedSourceCode
   * @param {!Formatter.FormatterSourceMapping} mapping
   */
  constructor(originalSourceCode, formattedSourceCode, mapping) {
    this.originalSourceCode = originalSourceCode;
    this.formattedSourceCode = formattedSourceCode;
    this.mapping = mapping;
  }

  originalPath() {
    return this.originalSourceCode.project().id() + ':' + this.originalSourceCode.url();
  }

  /**
   * @param {!Object} object
   * @return {?Sources.SourceFormatData}
   */
  static _for(object) {
    return object[Sources.SourceFormatData._formatDataSymbol];
  }
};

Sources.SourceFormatData._formatDataSymbol = Symbol('formatData');

Sources.SourceFormatter = class {
  constructor() {
    this._projectId = 'formatter:';
    this._project = new Bindings.ContentProviderBasedProject(
        Workspace.workspace, this._projectId, Workspace.projectTypes.Formatter, 'formatter',
        true /* isServiceProject */);

    /** @type {!Map<!Workspace.UISourceCode, !{promise: !Promise<!Sources.SourceFormatData>, formatData: ?Sources.SourceFormatData}>} */
    this._formattedSourceCodes = new Map();
    this._scriptMapping = new Sources.SourceFormatter.ScriptMapping();
    this._styleMapping = new Sources.SourceFormatter.StyleMapping();
    Workspace.workspace.addEventListener(
        Workspace.Workspace.Events.UISourceCodeRemoved, this._onUISourceCodeRemoved, this);
  }

  /**
   * @param {!Common.Event} event
   */
  _onUISourceCodeRemoved(event) {
    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
    const cacheEntry = this._formattedSourceCodes.get(uiSourceCode);
    if (cacheEntry && cacheEntry.formatData)
      this._discardFormatData(cacheEntry.formatData);
    this._formattedSourceCodes.remove(uiSourceCode);
  }

  /**
   * @param {!Workspace.UISourceCode} formattedUISourceCode
   * @return {?Workspace.UISourceCode}
   */
  discardFormattedUISourceCode(formattedUISourceCode) {
    const formatData = Sources.SourceFormatData._for(formattedUISourceCode);
    if (!formatData)
      return null;
    this._discardFormatData(formatData);
    this._formattedSourceCodes.remove(formatData.originalSourceCode);
    return formatData.originalSourceCode;
  }

  /**
   * @param {!Sources.SourceFormatData} formatData
   */
  _discardFormatData(formatData) {
    delete formatData.formattedSourceCode[Sources.SourceFormatData._formatDataSymbol];
    this._scriptMapping._setSourceMappingEnabled(formatData, false);
    this._styleMapping._setSourceMappingEnabled(formatData, false);
    this._project.removeFile(formatData.formattedSourceCode.url());
  }

  /**
   * @param {!Workspace.UISourceCode} uiSourceCode
   * @return {boolean}
   */
  hasFormatted(uiSourceCode) {
    return this._formattedSourceCodes.has(uiSourceCode);
  }

  /**
   * @param {!Workspace.UISourceCode} uiSourceCode
   * @return {!Promise<!Sources.SourceFormatData>}
   */
  async format(uiSourceCode) {
    const cacheEntry = this._formattedSourceCodes.get(uiSourceCode);
    if (cacheEntry)
      return cacheEntry.promise;

    let fulfillFormatPromise;
    const resultPromise = new Promise(fulfill => {
      fulfillFormatPromise = fulfill;
    });
    this._formattedSourceCodes.set(uiSourceCode, {promise: resultPromise, formatData: null});
    const content = await uiSourceCode.requestContent();
    // ------------ ASYNC ------------
    Formatter.Formatter.format(
        uiSourceCode.contentType(), uiSourceCode.mimeType(), content || '', formatDone.bind(this));
    return resultPromise;

    /**
     * @this Sources.SourceFormatter
     * @param {string} formattedContent
     * @param {!Formatter.FormatterSourceMapping} formatterMapping
     */
    function formatDone(formattedContent, formatterMapping) {
      const cacheEntry = this._formattedSourceCodes.get(uiSourceCode);
      if (!cacheEntry || cacheEntry.promise !== resultPromise)
        return;
      let formattedURL;
      let count = 0;
      let suffix = '';
      do {
        formattedURL = `${uiSourceCode.url()}:formatted${suffix}`;
        suffix = `:${count++}`;
      } while (this._project.uiSourceCodeForURL(formattedURL));
      const contentProvider =
          Common.StaticContentProvider.fromString(formattedURL, uiSourceCode.contentType(), formattedContent);
      const formattedUISourceCode =
          this._project.addContentProvider(formattedURL, contentProvider, uiSourceCode.mimeType());
      const formatData = new Sources.SourceFormatData(uiSourceCode, formattedUISourceCode, formatterMapping);
      formattedUISourceCode[Sources.SourceFormatData._formatDataSymbol] = formatData;
      this._scriptMapping._setSourceMappingEnabled(formatData, true);
      this._styleMapping._setSourceMappingEnabled(formatData, true);
      cacheEntry.formatData = formatData;

      for (const decoration of uiSourceCode.allDecorations()) {
        const range = decoration.range();
        const startLocation = formatterMapping.originalToFormatted(range.startLine, range.startColumn);
        const endLocation = formatterMapping.originalToFormatted(range.endLine, range.endColumn);

        formattedUISourceCode.addDecoration(
            new TextUtils.TextRange(startLocation[0], startLocation[1], endLocation[0], endLocation[1]),
            /** @type {string} */ (decoration.type()), decoration.data());
      }

      fulfillFormatPromise(formatData);
    }
  }
};

/**
 * @implements {Bindings.DebuggerSourceMapping}
 */
Sources.SourceFormatter.ScriptMapping = class {
  constructor() {
    Bindings.debuggerWorkspaceBinding.addSourceMapping(this);
  }

  /**
   * @override
   * @param {!SDK.DebuggerModel.Location} rawLocation
   * @return {?Workspace.UILocation}
   */
  rawLocationToUILocation(rawLocation) {
    const script = rawLocation.script();
    const formatData = script && Sources.SourceFormatData._for(script);
    if (!formatData)
      return null;
    const lineNumber = rawLocation.lineNumber;
    const columnNumber = rawLocation.columnNumber || 0;
    const formattedLocation = formatData.mapping.originalToFormatted(lineNumber, columnNumber);
    return formatData.formattedSourceCode.uiLocation(formattedLocation[0], formattedLocation[1]);
  }

  /**
   * @override
   * @param {!Workspace.UISourceCode} uiSourceCode
   * @param {number} lineNumber
   * @param {number} columnNumber
   * @return {?SDK.DebuggerModel.Location}
   */
  uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {
    const formatData = Sources.SourceFormatData._for(uiSourceCode);
    if (!formatData)
      return null;
    const originalLocation = formatData.mapping.formattedToOriginal(lineNumber, columnNumber);
    const scripts = this._scriptsForUISourceCode(formatData.originalSourceCode);
    if (!scripts.length)
      return null;
    return scripts[0].debuggerModel.createRawLocation(scripts[0], originalLocation[0], originalLocation[1]);
  }

  /**
   * @param {!Sources.SourceFormatData} formatData
   * @param {boolean} enabled
   */
  _setSourceMappingEnabled(formatData, enabled) {
    const scripts = this._scriptsForUISourceCode(formatData.originalSourceCode);
    if (!scripts.length)
      return;
    if (enabled) {
      for (const script of scripts)
        script[Sources.SourceFormatData._formatDataSymbol] = formatData;
    } else {
      for (const script of scripts)
        delete script[Sources.SourceFormatData._formatDataSymbol];
    }
    for (const script of scripts)
      Bindings.debuggerWorkspaceBinding.updateLocations(script);
  }

  /**
   * @param {!Workspace.UISourceCode} uiSourceCode
   * @return {!Array<!SDK.Script>}
   */
  _scriptsForUISourceCode(uiSourceCode) {
    if (uiSourceCode.contentType() === Common.resourceTypes.Document) {
      const target = Bindings.NetworkProject.targetForUISourceCode(uiSourceCode);
      const debuggerModel = target && target.model(SDK.DebuggerModel);
      if (debuggerModel) {
        const scripts = debuggerModel.scriptsForSourceURL(uiSourceCode.url())
                            .filter(script => script.isInlineScript() && !script.hasSourceURL);
        return scripts;
      }
    }
    if (uiSourceCode.contentType().isScript()) {
      const rawLocation = Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(uiSourceCode, 0, 0);
      if (rawLocation)
        return [rawLocation.script()];
    }
    return [];
  }
};

/**
 * @implements {Bindings.CSSWorkspaceBinding.SourceMapping}
 */
Sources.SourceFormatter.StyleMapping = class {
  constructor() {
    Bindings.cssWorkspaceBinding.addSourceMapping(this);
    this._headersSymbol = Symbol('Sources.SourceFormatter.StyleMapping._headersSymbol');
  }

  /**
   * @override
   * @param {!SDK.CSSLocation} rawLocation
   * @return {?Workspace.UILocation}
   */
  rawLocationToUILocation(rawLocation) {
    const styleHeader = rawLocation.header();
    const formatData = styleHeader && Sources.SourceFormatData._for(styleHeader);
    if (!formatData)
      return null;
    const formattedLocation =
        formatData.mapping.originalToFormatted(rawLocation.lineNumber, rawLocation.columnNumber || 0);
    return formatData.formattedSourceCode.uiLocation(formattedLocation[0], formattedLocation[1]);
  }

  /**
   * @override
   * @param {!Workspace.UILocation} uiLocation
   * @return {!Array<!SDK.CSSLocation>}
   */
  uiLocationToRawLocations(uiLocation) {
    const formatData = Sources.SourceFormatData._for(uiLocation.uiSourceCode);
    if (!formatData)
      return [];
    const originalLocation = formatData.mapping.formattedToOriginal(uiLocation.lineNumber, uiLocation.columnNumber);
    const headers = formatData.originalSourceCode[this._headersSymbol];
    return headers.map(header => new SDK.CSSLocation(header, originalLocation[0], originalLocation[1]));
  }

  /**
   * @param {!Sources.SourceFormatData} formatData
   * @param {boolean} enable
   */
  _setSourceMappingEnabled(formatData, enable) {
    const original = formatData.originalSourceCode;
    const rawLocations = Bindings.cssWorkspaceBinding.uiLocationToRawLocations(original.uiLocation(0, 0));
    const headers = rawLocations.map(rawLocation => rawLocation.header()).filter(header => !!header);
    if (!headers.length)
      return;
    if (enable) {
      original[this._headersSymbol] = headers;
      headers.forEach(header => header[Sources.SourceFormatData._formatDataSymbol] = formatData);
    } else {
      original[this._headersSymbol] = null;
      headers.forEach(header => delete header[Sources.SourceFormatData._formatDataSymbol]);
    }
    headers.forEach(header => Bindings.cssWorkspaceBinding.updateLocations(header));
  }
};

Sources.sourceFormatter = new Sources.SourceFormatter();
