// Copyright (c) 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.

export default class NetworkPersistenceManager extends Common.Object {
  /**
   * @param {!Workspace.Workspace} workspace
   */
  constructor(workspace) {
    super();
    this._bindingSymbol = Symbol('NetworkPersistenceBinding');
    this._originalResponseContentPromiseSymbol = Symbol('OriginalResponsePromise');
    this._savingSymbol = Symbol('SavingForOverrides');

    this._enabledSetting = Common.settings.moduleSetting('persistenceNetworkOverridesEnabled');
    this._enabledSetting.addChangeListener(this._enabledChanged, this);

    this._workspace = workspace;

    /** @type {!Map<string, !Workspace.UISourceCode>} */
    this._networkUISourceCodeForEncodedPath = new Map();
    this._interceptionHandlerBound = this._interceptionHandler.bind(this);
    this._updateInterceptionThrottler = new Common.Throttler(50);

    /** @type {?Workspace.Project} */
    this._project = null;
    /** @type {?Workspace.Project} */
    this._activeProject = null;

    this._active = false;
    this._enabled = false;

    this._workspace.addEventListener(
        Workspace.Workspace.Events.ProjectAdded,
        event => this._onProjectAdded(/** @type {!Workspace.Project} */ (event.data)));
    this._workspace.addEventListener(
        Workspace.Workspace.Events.ProjectRemoved,
        event => this._onProjectRemoved(/** @type {!Workspace.Project} */ (event.data)));

    Persistence.persistence.addNetworkInterceptor(this._canHandleNetworkUISourceCode.bind(this));

    /** @type {!Array<!Common.EventTarget.EventDescriptor>} */
    this._eventDescriptors = [];
    this._enabledChanged();
  }

  /**
   * @return {boolean}
   */
  active() {
    return this._active;
  }

  /**
   * @return {?Workspace.Project}
   */
  project() {
    return this._project;
  }


  /**
   * @param {!Workspace.UISourceCode} uiSourceCode
   * @return {?Promise<?string>}
   */
  originalContentForUISourceCode(uiSourceCode) {
    if (!uiSourceCode[this._bindingSymbol]) {
      return null;
    }
    const fileSystemUISourceCode = uiSourceCode[this._bindingSymbol].fileSystem;
    return fileSystemUISourceCode[this._originalResponseContentPromiseSymbol] || null;
  }

  _enabledChanged() {
    if (this._enabled === this._enabledSetting.get()) {
      return;
    }
    this._enabled = this._enabledSetting.get();
    if (this._enabled) {
      this._eventDescriptors = [
        Workspace.workspace.addEventListener(
            Workspace.Workspace.Events.UISourceCodeRenamed,
            event => {
              const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data.uiSourceCode);
              this._onUISourceCodeRemoved(uiSourceCode);
              this._onUISourceCodeAdded(uiSourceCode);
            }),
        Workspace.workspace.addEventListener(
            Workspace.Workspace.Events.UISourceCodeAdded,
            event => this._onUISourceCodeAdded(/** @type {!Workspace.UISourceCode} */ (event.data))),
        Workspace.workspace.addEventListener(
            Workspace.Workspace.Events.UISourceCodeRemoved,
            event => this._onUISourceCodeRemoved(/** @type {!Workspace.UISourceCode} */ (event.data))),
        Workspace.workspace.addEventListener(
            Workspace.Workspace.Events.WorkingCopyCommitted,
            event => this._onUISourceCodeWorkingCopyCommitted(
                /** @type {!Workspace.UISourceCode} */ (event.data.uiSourceCode)))
      ];
      this._updateActiveProject();
    } else {
      Common.EventTarget.removeEventListeners(this._eventDescriptors);
      this._updateActiveProject();
    }
  }

  _updateActiveProject() {
    const wasActive = this._active;
    this._active = !!(this._enabledSetting.get() && SDK.targetManager.mainTarget() && this._project);
    if (this._active === wasActive) {
      return;
    }

    if (this._active) {
      this._project.uiSourceCodes().forEach(this._filesystemUISourceCodeAdded.bind(this));
      const networkProjects = this._workspace.projectsForType(Workspace.projectTypes.Network);
      for (const networkProject of networkProjects) {
        networkProject.uiSourceCodes().forEach(this._networkUISourceCodeAdded.bind(this));
      }
    } else if (this._project) {
      this._project.uiSourceCodes().forEach(this._filesystemUISourceCodeRemoved.bind(this));
      this._networkUISourceCodeForEncodedPath.clear();
    }
    Persistence.persistence.refreshAutomapping();
  }

  /**
   * @param {string} url
   * @return {string}
   */
  _encodedPathFromUrl(url) {
    if (!this._active) {
      return '';
    }
    let urlPath = Common.ParsedURL.urlWithoutHash(url.replace(/^https?:\/\//, ''));
    if (urlPath.endsWith('/') && urlPath.indexOf('?') === -1) {
      urlPath = urlPath + 'index.html';
    }
    let encodedPathParts = encodeUrlPathToLocalPathParts(urlPath);
    const projectPath = Persistence.FileSystemWorkspaceBinding.fileSystemPath(this._project.id());
    const encodedPath = encodedPathParts.join('/');
    if (projectPath.length + encodedPath.length > 200) {
      const domain = encodedPathParts[0];
      const encodedFileName = encodedPathParts[encodedPathParts.length - 1];
      const shortFileName = encodedFileName ? encodedFileName.substr(0, 10) + '-' : '';
      const extension = Common.ParsedURL.extractExtension(urlPath);
      const extensionPart = extension ? '.' + extension.substr(0, 10) : '';
      encodedPathParts =
          [domain, 'longurls', shortFileName + String.hashCode(encodedPath).toString(16) + extensionPart];
    }
    return encodedPathParts.join('/');

    /**
     * @param {string} urlPath
     * @return {!Array<string>}
     */
    function encodeUrlPathToLocalPathParts(urlPath) {
      const encodedParts = [];
      for (const pathPart of fileNamePartsFromUrlPath(urlPath)) {
        if (!pathPart) {
          continue;
        }
        // encodeURI() escapes all the unsafe filename characters except /:?*
        let encodedName = encodeURI(pathPart).replace(/[\/:\?\*]/g, match => '%' + match[0].charCodeAt(0).toString(16));
        // Windows does not allow a small set of filenames.
        if (_reservedFileNames.has(encodedName.toLowerCase())) {
          encodedName = encodedName.split('').map(char => '%' + char.charCodeAt(0).toString(16)).join('');
        }
        // Windows does not allow the file to end in a space or dot (space should already be encoded).
        const lastChar = encodedName.charAt(encodedName.length - 1);
        if (lastChar === '.') {
          encodedName = encodedName.substr(0, encodedName.length - 1) + '%2e';
        }
        encodedParts.push(encodedName);
      }
      return encodedParts;
    }

    /**
     * @param {string} urlPath
     * @return {!Array<string>}
     */
    function fileNamePartsFromUrlPath(urlPath) {
      urlPath = Common.ParsedURL.urlWithoutHash(urlPath);
      const queryIndex = urlPath.indexOf('?');
      if (queryIndex === -1) {
        return urlPath.split('/');
      }
      if (queryIndex === 0) {
        return [urlPath];
      }
      const endSection = urlPath.substr(queryIndex);
      const parts = urlPath.substr(0, urlPath.length - endSection.length).split('/');
      parts[parts.length - 1] += endSection;
      return parts;
    }
  }

  /**
   * @param {string} path
   * @return {string}
   */
  _decodeLocalPathToUrlPath(path) {
    try {
      return unescape(path);
    } catch (e) {
      console.error(e);
    }
    return path;
  }

  /**
   * @param {!Workspace.UISourceCode} uiSourceCode
   */
  _unbind(uiSourceCode) {
    const binding = uiSourceCode[this._bindingSymbol];
    if (!binding) {
      return;
    }
    delete binding.network[this._bindingSymbol];
    delete binding.fileSystem[this._bindingSymbol];
    Persistence.persistence.removeBinding(binding);
  }

  /**
   * @param {!Workspace.UISourceCode} networkUISourceCode
   * @param {!Workspace.UISourceCode} fileSystemUISourceCode
   */
  async _bind(networkUISourceCode, fileSystemUISourceCode) {
    if (networkUISourceCode[this._bindingSymbol]) {
      this._unbind(networkUISourceCode);
    }
    if (fileSystemUISourceCode[this._bindingSymbol]) {
      this._unbind(fileSystemUISourceCode);
    }
    const binding = new Persistence.PersistenceBinding(networkUISourceCode, fileSystemUISourceCode);
    networkUISourceCode[this._bindingSymbol] = binding;
    fileSystemUISourceCode[this._bindingSymbol] = binding;
    Persistence.persistence.addBinding(binding);
    const uiSourceCodeOfTruth = networkUISourceCode[this._savingSymbol] ? networkUISourceCode : fileSystemUISourceCode;
    const [{content}, encoded] =
        await Promise.all([uiSourceCodeOfTruth.requestContent(), uiSourceCodeOfTruth.contentEncoded()]);
    Persistence.persistence.syncContent(uiSourceCodeOfTruth, content, encoded);
  }

  /**
   * @param {!Workspace.UISourceCode} uiSourceCode
   */
  _onUISourceCodeWorkingCopyCommitted(uiSourceCode) {
    this.saveUISourceCodeForOverrides(uiSourceCode);
  }

  /**
   * @param {!Workspace.UISourceCode} uiSourceCode
   */
  canSaveUISourceCodeForOverrides(uiSourceCode) {
    return this._active && uiSourceCode.project().type() === Workspace.projectTypes.Network &&
        !uiSourceCode[this._bindingSymbol] && !uiSourceCode[this._savingSymbol];
  }

  /**
   * @param {!Workspace.UISourceCode} uiSourceCode
   */
  async saveUISourceCodeForOverrides(uiSourceCode) {
    if (!this.canSaveUISourceCodeForOverrides(uiSourceCode)) {
      return;
    }
    uiSourceCode[this._savingSymbol] = true;
    let encodedPath = this._encodedPathFromUrl(uiSourceCode.url());
    const content = (await uiSourceCode.requestContent()).content || '';
    const encoded = await uiSourceCode.contentEncoded();
    const lastIndexOfSlash = encodedPath.lastIndexOf('/');
    const encodedFileName = encodedPath.substr(lastIndexOfSlash + 1);
    encodedPath = encodedPath.substr(0, lastIndexOfSlash);
    await this._project.createFile(encodedPath, encodedFileName, content, encoded);
    this._fileCreatedForTest(encodedPath, encodedFileName);
    uiSourceCode[this._savingSymbol] = false;
  }

  /**
   * @param {string} path
   * @param {string} fileName
   */
  _fileCreatedForTest(path, fileName) {
  }

  /**
   * @param {!Workspace.UISourceCode} uiSourceCode
   * @return {string}
   */
  _patternForFileSystemUISourceCode(uiSourceCode) {
    const relativePathParts = Persistence.FileSystemWorkspaceBinding.relativePath(uiSourceCode);
    if (relativePathParts.length < 2) {
      return '';
    }
    if (relativePathParts[1] === 'longurls' && relativePathParts.length !== 2) {
      return 'http?://' + relativePathParts[0] + '/*';
    }
    return 'http?://' + this._decodeLocalPathToUrlPath(relativePathParts.join('/'));
  }

  /**
   * @param {!Workspace.UISourceCode} uiSourceCode
   */
  _onUISourceCodeAdded(uiSourceCode) {
    this._networkUISourceCodeAdded(uiSourceCode);
    this._filesystemUISourceCodeAdded(uiSourceCode);
  }

  /**
   * @param {!Workspace.UISourceCode} uiSourceCode
   */
  _canHandleNetworkUISourceCode(uiSourceCode) {
    return this._active && !uiSourceCode.url().startsWith('snippet://');
  }

  /**
   * @param {!Workspace.UISourceCode} uiSourceCode
   */
  _networkUISourceCodeAdded(uiSourceCode) {
    if (uiSourceCode.project().type() !== Workspace.projectTypes.Network ||
        !this._canHandleNetworkUISourceCode(uiSourceCode)) {
      return;
    }
    const url = Common.ParsedURL.urlWithoutHash(uiSourceCode.url());
    this._networkUISourceCodeForEncodedPath.set(this._encodedPathFromUrl(url), uiSourceCode);

    const fileSystemUISourceCode = this._project.uiSourceCodeForURL(
        /** @type {!Persistence.FileSystemWorkspaceBinding.FileSystem} */ (this._project).fileSystemPath() + '/' +
        this._encodedPathFromUrl(url));
    if (!fileSystemUISourceCode) {
      return;
    }
    this._bind(uiSourceCode, fileSystemUISourceCode);
  }

  /**
    * @param {!Workspace.UISourceCode} uiSourceCode
    */
  _filesystemUISourceCodeAdded(uiSourceCode) {
    if (!this._active || uiSourceCode.project() !== this._project) {
      return;
    }
    this._updateInterceptionPatterns();

    const relativePath = Persistence.FileSystemWorkspaceBinding.relativePath(uiSourceCode);
    const networkUISourceCode = this._networkUISourceCodeForEncodedPath.get(relativePath.join('/'));
    if (networkUISourceCode) {
      this._bind(networkUISourceCode, uiSourceCode);
    }
  }

  _updateInterceptionPatterns() {
    this._updateInterceptionThrottler.schedule(innerUpdateInterceptionPatterns.bind(this));

    /**
     * @this {NetworkPersistenceManager}
     * @return {!Promise}
     */
    function innerUpdateInterceptionPatterns() {
      if (!this._active) {
        return SDK.multitargetNetworkManager.setInterceptionHandlerForPatterns([], this._interceptionHandlerBound);
      }
      const patterns = new Set();
      const indexFileName = 'index.html';
      for (const uiSourceCode of this._project.uiSourceCodes()) {
        const pattern = this._patternForFileSystemUISourceCode(uiSourceCode);
        patterns.add(pattern);
        if (pattern.endsWith('/' + indexFileName)) {
          patterns.add(pattern.substr(0, pattern.length - indexFileName.length));
        }
      }

      return SDK.multitargetNetworkManager.setInterceptionHandlerForPatterns(
          Array.from(patterns).map(
              pattern =>
                  ({urlPattern: pattern, interceptionStage: Protocol.Network.InterceptionStage.HeadersReceived})),
          this._interceptionHandlerBound);
    }
  }

  /**
   * @param {!Workspace.UISourceCode} uiSourceCode
   */
  _onUISourceCodeRemoved(uiSourceCode) {
    this._networkUISourceCodeRemoved(uiSourceCode);
    this._filesystemUISourceCodeRemoved(uiSourceCode);
  }

  /**
   * @param {!Workspace.UISourceCode} uiSourceCode
   */
  _networkUISourceCodeRemoved(uiSourceCode) {
    if (uiSourceCode.project().type() !== Workspace.projectTypes.Network) {
      return;
    }
    this._unbind(uiSourceCode);
    this._networkUISourceCodeForEncodedPath.delete(this._encodedPathFromUrl(uiSourceCode.url()));
  }

  /**
   * @param {!Workspace.UISourceCode} uiSourceCode
   */
  _filesystemUISourceCodeRemoved(uiSourceCode) {
    if (uiSourceCode.project() !== this._project) {
      return;
    }
    this._updateInterceptionPatterns();
    delete uiSourceCode[this._originalResponseContentPromiseSymbol];
    this._unbind(uiSourceCode);
  }

  _setProject(project) {
    if (project === this._project) {
      return;
    }

    if (this._project) {
      this._project.uiSourceCodes().forEach(this._filesystemUISourceCodeRemoved.bind(this));
    }

    this._project = project;

    if (this._project) {
      this._project.uiSourceCodes().forEach(this._filesystemUISourceCodeAdded.bind(this));
    }

    this._updateActiveProject();
    this.dispatchEventToListeners(Events.ProjectChanged, this._project);
  }

  /**
   * @param {!Workspace.Project} project
   */
  _onProjectAdded(project) {
    if (project.type() !== Workspace.projectTypes.FileSystem ||
        Persistence.FileSystemWorkspaceBinding.fileSystemType(project) !== 'overrides') {
      return;
    }
    const fileSystemPath = Persistence.FileSystemWorkspaceBinding.fileSystemPath(project.id());
    if (!fileSystemPath) {
      return;
    }
    if (this._project) {
      this._project.remove();
    }

    this._setProject(project);
  }

  /**
   * @param {!Workspace.Project} project
   */
  _onProjectRemoved(project) {
    if (project !== this._project) {
      return;
    }
    this._setProject(null);
  }

  /**
   * @param {!SDK.MultitargetNetworkManager.InterceptedRequest} interceptedRequest
   * @return {!Promise}
   */
  async _interceptionHandler(interceptedRequest) {
    const method = interceptedRequest.request.method;
    if (!this._active || (method !== 'GET' && method !== 'POST')) {
      return;
    }
    const path = /** @type {!Persistence.FileSystemWorkspaceBinding.FileSystem} */ (this._project).fileSystemPath() +
        '/' + this._encodedPathFromUrl(interceptedRequest.request.url);
    const fileSystemUISourceCode = this._project.uiSourceCodeForURL(path);
    if (!fileSystemUISourceCode) {
      return;
    }

    let mimeType = '';
    if (interceptedRequest.responseHeaders) {
      const responseHeaders = SDK.NetworkManager.lowercaseHeaders(interceptedRequest.responseHeaders);
      mimeType = responseHeaders['content-type'];
    }

    if (!mimeType) {
      const expectedResourceType = Common.resourceTypes[interceptedRequest.resourceType] || Common.resourceTypes.Other;
      mimeType = fileSystemUISourceCode.mimeType();
      if (Common.ResourceType.fromMimeType(mimeType) !== expectedResourceType) {
        mimeType = expectedResourceType.canonicalMimeType();
      }
    }
    const project =
        /** @type {!Persistence.FileSystemWorkspaceBinding.FileSystem} */ (fileSystemUISourceCode.project());

    fileSystemUISourceCode[this._originalResponseContentPromiseSymbol] =
        interceptedRequest.responseBody().then(response => {
          if (response.error || response.content === null) {
            return null;
          }
          return response.encoded ? atob(response.content) : response.content;
        });

    const blob = await project.requestFileBlob(fileSystemUISourceCode);
    interceptedRequest.continueRequestWithContent(new Blob([blob], {type: mimeType}));
  }
}

const _reservedFileNames = new Set([
  'con',  'prn',  'aux',  'nul',  'com1', 'com2', 'com3', 'com4', 'com5', 'com6', 'com7',
  'com8', 'com9', 'lpt1', 'lpt2', 'lpt3', 'lpt4', 'lpt5', 'lpt6', 'lpt7', 'lpt8', 'lpt9'
]);

export const Events = {
  ProjectChanged: Symbol('ProjectChanged')
};

/* Legacy exported object */
self.Persistence = self.Persistence || {};

/* Legacy exported object */
Persistence = Persistence || {};

/** @constructor */
Persistence.NetworkPersistenceManager = NetworkPersistenceManager;

Persistence.NetworkPersistenceManager.Events = Events;

/** @type {!NetworkPersistenceManager} */
Persistence.networkPersistenceManager;
