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

import 'chrome://resources/cr_elements/cr_button/cr_button.js';
import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
import 'chrome://resources/cr_elements/cr_input/cr_input.js';
import 'chrome://resources/cr_elements/icons.html.js';
import 'chrome://resources/cr_elements/cr_icon/cr_icon.js';
import '/strings.m.js';

import type {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js';
import type {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
import {I18nMixinLit} from 'chrome://resources/cr_elements/i18n_mixin_lit.js';
import {assert} from 'chrome://resources/js/assert.js';
import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
import {CrLitElement} from 'chrome://resources/lit/v3_0/lit.rollup.js';
import type {PropertyValues} from 'chrome://resources/lit/v3_0/lit.rollup.js';

import {getHtml} from './runtime_hosts_dialog.html.js';
import {getCss as getSharedStyleCss} from './shared_style.css.js';
import {sitePermissionsPatternRegExp} from './site_permissions/site_permissions_edit_url_dialog.js';
import {SiteSettingsMixin} from './site_permissions/site_settings_mixin.js';

// A RegExp to roughly match acceptable patterns entered by the user.
// exec'ing() this RegExp will match the following groups:
// 0: Full matched string.
// 1: Scheme + scheme separator (e.g., 'https://').
// 2: Scheme only (e.g., 'https').
// 3: Match subdomains ('*.').
// 4: Hostname (e.g., 'example.com').
// 5: Port, including ':' separator (e.g., ':80').
// 6: Path, include '/' separator (e.g., '/*').
const runtimeHostsPatternRegExp = new RegExp(
    '^' +
    // Scheme; optional.
    '((http|https|\\*)://)?' +
    // Include subdomains specifier; optional.
    '(\\*\\.)?' +
    // Hostname or localhost, required.
    '([a-z0-9\\.-]+\\.[a-z0-9]+|localhost)' +
    // Port, optional.
    '(:[0-9]+)?' +
    // Path, optional but if present must be '/' or '/*'.
    '(\\/\\*|\\/)?' +
    '$');

export function getPatternFromSite(site: string): string {
  const res = runtimeHostsPatternRegExp.exec(site)!;
  assert(res);
  const scheme = res[1] || '*://';
  const host = (res[3] || '') + res[4];
  const port = res[5] || '';
  const path = '/*';
  return scheme + host + port + path;
}

// Returns the sublist of `userSites` which match the pattern specified by
// `host`.
export function getMatchingUserSpecifiedSites(
    userSites: string[], host: string): string[] {
  if (!runtimeHostsPatternRegExp.test(host)) {
    return [];
  }

  const newHostRes = runtimeHostsPatternRegExp.exec(host);
  assert(newHostRes);

  const matchAllSchemes = !newHostRes[1] || newHostRes[1] === '*://';
  const matchAllSubdomains = newHostRes[3] === '*.';

  // For each restricted site, break it down into
  // `sitePermissionsPatternRegExp` components and check against components
  // from `newHostRes`.
  return userSites.filter((userSite: string) => {
    const siteRes = sitePermissionsPatternRegExp.exec(userSite);
    assert(siteRes);

    // Check if schemes match, unless `newHostRes` has a wildcard scheme.
    if (!matchAllSchemes && newHostRes[1] !== siteRes[1]) {
      return false;
    }

    // Check if host names match. If `matchAllSubdomains` is specified, check
    // that `newHostRes[4]` is a suffix of `siteRes[3]`
    if (matchAllSubdomains && !siteRes[3]!.endsWith(newHostRes[4]!)) {
      return false;
    }
    if (!matchAllSubdomains && siteRes[3] !== newHostRes[4]) {
      return false;
    }

    // Ports match if:
    //  - both are unspecified
    //  - both are specified and are an exact match
    //  - specified for `restrictedSite` but not `this,site_`
    return !newHostRes[5] || newHostRes[5] === siteRes[4];
  });
}

export interface ExtensionsRuntimeHostsDialogElement {
  $: {
    dialog: CrDialogElement,
    submit: CrButtonElement,
  };
}

const ExtensionsRuntimeHostsDialogElementBase =
    I18nMixinLit(SiteSettingsMixin(CrLitElement));

export class ExtensionsRuntimeHostsDialogElement extends
    ExtensionsRuntimeHostsDialogElementBase {
  static get is() {
    return 'extensions-runtime-hosts-dialog';
  }

  static override get styles() {
    return getSharedStyleCss();
  }

  override render() {
    return getHtml.bind(this)();
  }

  static override get properties() {
    return {
      ...super.properties,

      itemId: {type: String},

      /**
       * The site that this entry is currently managing. Only non-empty if this
       * is for editing an existing entry.
       */
      currentSite: {type: String},

      /**
       * Whether the dialog should update the host access to be "on specific
       * sites" before adding a new host permission.
       */
      updateHostAccess: {type: Boolean},

      /** The site to add an exception for. */
      site_: {type: String},

      /** Whether the currently-entered input is valid. */
      inputInvalid_: {type: Boolean},

      /**
       * the list of user specified restricted sites that match with `site_` if
       * `site_` is valid.
       */
      matchingRestrictedSites_: {type: Array},
    };
  }

  itemId: string = '';
  currentSite: string|null = null;
  updateHostAccess: boolean = false;
  protected site_: string = '';
  protected inputInvalid_: boolean = false;
  protected matchingRestrictedSites_: string[] = [];

  override connectedCallback() {
    super.connectedCallback();

    if (this.currentSite !== null && this.currentSite !== undefined) {
      this.site_ = this.currentSite;
      this.validate_();
    }
    this.$.dialog.showModal();
  }

  override willUpdate(changedProperties: PropertyValues<this>) {
    super.willUpdate(changedProperties);

    const changedPrivateProperties =
        changedProperties as Map<PropertyKey, unknown>;
    if (changedProperties.has('restrictedSites') ||
        changedPrivateProperties.has('site_')) {
      this.matchingRestrictedSites_ = this.computeMatchingRestrictedSites_();
    }
  }

  isOpen(): boolean {
    return this.$.dialog.open;
  }

  /**
   * Validates that the pattern entered is valid.
   */
  protected validate_() {
    // If input is empty, disable the action button, but don't show the red
    // invalid message.
    if (this.site_.trim().length === 0) {
      this.inputInvalid_ = false;
      return;
    }

    this.inputInvalid_ = !runtimeHostsPatternRegExp.test(this.site_);
  }

  protected onSiteChanged_(e: CustomEvent<{value: string}>) {
    this.site_ = e.detail.value;
  }

  protected computeDialogTitle_(): string {
    const stringId = this.currentSite === null ? 'runtimeHostsDialogTitle' :
                                                 'hostPermissionsEdit';
    return loadTimeData.getString(stringId);
  }

  protected computeSubmitButtonDisabled_(): boolean {
    return this.inputInvalid_ || this.site_ === undefined ||
        this.site_.trim().length === 0;
  }

  protected computeSubmitButtonLabel_(): string {
    const stringId = this.currentSite === null ? 'add' : 'save';
    return loadTimeData.getString(stringId);
  }

  private computeMatchingRestrictedSites_(): string[] {
    return getMatchingUserSpecifiedSites(this.restrictedSites, this.site_);
  }

  protected onCancelClick_() {
    this.$.dialog.cancel();
  }

  /**
   * The tap handler for the submit button (adds the pattern and closes
   * the dialog).
   */
  protected onSubmitClick_() {
    chrome.metricsPrivate.recordUserAction(
        'Extensions.Settings.Hosts.AddHostDialogSubmitted');
    if (this.currentSite !== null) {
      this.handleEdit_();
    } else {
      this.handleAdd_();
    }
  }

  /**
   * Handles adding a new site entry.
   */
  private handleAdd_() {
    assert(!this.currentSite);

    if (this.updateHostAccess) {
      this.delegate.setItemHostAccess(
          this.itemId, chrome.developerPrivate.HostAccess.ON_SPECIFIC_SITES);
    }

    this.addPermission_();
  }

  /**
   * Handles editing an existing site entry.
   */
  private handleEdit_() {
    assert(this.currentSite);
    assert(
        !this.updateHostAccess,
        'Editing host permissions should only be possible if the host ' +
            'access is already set to specific sites.');

    if (this.currentSite === this.site_) {
      // No change in values, so no need to update anything.
      this.$.dialog.close();
      return;
    }

    // Editing an existing entry is done by removing the current site entry,
    // and then adding the new one.
    this.delegate.removeRuntimeHostPermission(this.itemId, this.currentSite)
        .then(() => {
          this.addPermission_();
        });
  }

  /**
   * Adds the runtime host permission through the delegate. If successful,
   * closes the dialog; otherwise displays the invalid input message.
   */
  private addPermission_() {
    const pattern = getPatternFromSite(this.site_);
    const restrictedSites = this.matchingRestrictedSites_;
    this.delegate.addRuntimeHostPermission(this.itemId, pattern)
        .then(
            () => {
              if (restrictedSites.length) {
                this.delegate.removeUserSpecifiedSites(
                    chrome.developerPrivate.SiteSet.USER_RESTRICTED,
                    restrictedSites);
              }
              this.$.dialog.close();
            },
            () => {
              this.inputInvalid_ = true;
            });
  }

  /**
   * Returns a warning message containing the first restricted site that
   * overlaps with `this.site_`, or an empty string if there are no matching
   * restricted sites.
   */
  protected computeMatchingRestrictedSitesWarning_(): string {
    return this.matchingRestrictedSites_.length ?
        this.i18n(
            'matchingRestrictedSitesWarning',
            this.matchingRestrictedSites_[0]!,
            ) :
        '';
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'extensions-runtime-hosts-dialog': ExtensionsRuntimeHostsDialogElement;
  }
}

customElements.define(
    ExtensionsRuntimeHostsDialogElement.is,
    ExtensionsRuntimeHostsDialogElement);
