import actionApi from './actionApi.js';
import optionsPrototype from './optionsPrototype.json5';
import {getOptions} from './optionsUtils.js';

// Required permissions, including host permissions.
//
// IMPORTANT: This should be kept in sync with the "permissions",
// "host_permissions" and "content_scripts" keys in //templates/manifest.gjson.
const requiredPermissions = {
  permissions: new Set([
    'storage', 'alarms',
    // #!if ['chromium', 'chromium_mv3'].includes(browser_target)
    'declarativeNetRequestWithHostAccess',
    // #!endif
    // #!if browser_target == 'chromium_mv3'
    'scripting',
    // #!endif
  ]),
  origins: new Set([
    // Host permissions:
    'https://support.google.com/*',

    // Content scripts matches:
    'https://support.google.com/s/community*',
    'https://support.google.com/*/threads*',
    'https://support.google.com/*/thread/*',
    'https://support.google.com/*/profile/*',
    'https://support.google.com/profile/*',
  ]),
};

const permissionTypes = ['origins', 'permissions'];

// Returns an array of optional permissions needed by |feature|.
export function requiredOptPermissions(feature) {
  if (!(feature in optionsPrototype)) {
    console.error('"' + feature + '" feature doesn\'t exist.');
    return [];
  }

  return optionsPrototype[feature]?.requiredOptPermissions ?? [];
}

// Returns a promise resolving to the optional permissions needed by all the
// current enabled features.
export function currentRequiredOptPermissions() {
  return getOptions(null, /* requireOptionalPermissions = */ false)
      .then(options => {
        let permissions = {
          origins: [],
          permissions: [],
        };

        // For each option
        for (const [opt, optMeta] of Object.entries(optionsPrototype))
          // If the option is enabled
          if (options[opt])
            // Add its required optional permissions to the list
            for (const type of permissionTypes)
              permissions[type].push(
                  ...(optMeta.requiredOptPermissions?.[type] ?? []));

        return permissions;
      });
}

// Ensures that all the optional permissions required by |feature| are granted,
// and requests them otherwise. It returns a promise which resolves specifying
// whether the permissions were granted or not.
export function ensureOptPermissions(feature) {
  return new Promise((resolve, reject) => {
    let permissions = requiredOptPermissions(feature);

    chrome.permissions.contains(permissions, isAlreadyGranted => {
      if (isAlreadyGranted) return resolve(true);

      chrome.permissions.request(permissions, granted => {
        // If there was an error, reject the promise.
        if (granted === undefined)
          return reject(new Error(
              chrome.runtime.lastError.message ??
              'An unknown error occurred while requesting the permisisons'));

        // If the permission is granted we should maybe remove the warning
        // badge.
        if (granted) cleanUpOptPermissions(/* removeLeftoverPerms = */ false);

        return resolve(granted);
      });
    });
  });
}

// Returns a promise resolving to the currently granted optional permissions
// (i.e. excluding required permissions).
export function grantedOptPermissions() {
  return new Promise((resolve, reject) => {
    chrome.permissions.getAll(response => {
      if (response === undefined)
        return reject(new Error(
            chrome.runtime.lastError.message ??
            'An unknown error occurred while calling chrome.permissions.getAll()'));

      let optPermissions = {};
      for (const type of permissionTypes)
        optPermissions[type] =
            response[type].filter(p => !requiredPermissions[type].has(p));
      resolve(optPermissions);
    });
  });
}

// Returns a promise resolving to an object with 2 properties:
//   - missingPermissions: optional permissions which are required by enabled
//     features and haven't been granted yet.
//   - leftoverPermissions: optional permissions which are granted but are no
//     longer needed.
export function diffPermissions() {
  return Promise
      .all([
        grantedOptPermissions(),
        currentRequiredOptPermissions(),
      ])
      .then(perms => {
        let diff = {
          missingPermissions: {},
          leftoverPermissions: {},
        };
        for (const type of permissionTypes) {
          diff.missingPermissions[type] =
              perms[1][type].filter(p => !perms[0][type].includes(p));
          diff.leftoverPermissions[type] =
              perms[0][type].filter(p => !perms[1][type].includes(p));
        }
        return diff;
      })
      .catch(cause => {
        throw new Error(
            'Couldn\'t compute the missing and leftover permissions.', {cause});
      });
}

// Returns a promise which resolves to the required optional permissions of
// |feature| which are missing.
//
// Accepts an argument |grantedPermissions| with the granted permissions,
// otherwise the function will call grantedOptPermissions() to retrieve them.
// This can be used to prevent calling chrome.permissions.getAll() repeteadly.
export function missingPermissions(feature, grantedPermissions = null) {
  let grantedOptPermissionsPromise;
  if (grantedPermissions !== null)
    grantedOptPermissionsPromise = new Promise((res, rej) => {
      res(grantedPermissions);
    });
  else
    grantedOptPermissionsPromise = grantedOptPermissions();

  return Promise
      .all([
        grantedOptPermissionsPromise,
        requiredOptPermissions(feature),
      ])
      .then(perms => {
        let missingPerms = {};
        for (const type of permissionTypes)
          missingPerms[type] =
              perms[1][type].filter(p => !perms[0][type].includes(p))
          return missingPerms;
      })
      .catch(cause => {
        throw new Error(
            'Couldn\'t compute the missing permissions for "' + feature + '",',
            {cause});
      });
}

// Returns true if permissions (a chrome.permissions.Permissions object) is
// empty (that is, if their properties have empty arrays).
export function isPermissionsObjectEmpty(permissions) {
  for (const type of permissionTypes) {
    if ((permissions[type]?.length ?? 0) > 0) return false;
  }
  return true;
}

// Deletes optional permissions which are no longer needed by the current
// set of enabled features (if |removeLeftoverPerms| is set to true), and sets a
// badge if some needed permissions are missing.
export function cleanUpOptPermissions(removeLeftoverPerms = true) {
  return diffPermissions()
      .then(perms => {
        let {missingPermissions, leftoverPermissions} = perms;

        if (!isPermissionsObjectEmpty(missingPermissions)) {
          actionApi.setBadgeBackgroundColor({color: '#B71C1C'});
          actionApi.setBadgeText({text: '!'});
          actionApi.setTitle({
            title: chrome.i18n.getMessage('actionbadge_permissions_requested')
          });
        } else {
          actionApi.setBadgeText({text: ''});
          actionApi.setTitle({title: ''});
        }

        if (removeLeftoverPerms) {
          chrome.permissions.remove(leftoverPermissions);
        }
      })
      .catch(err => {
        console.error(
            'An error ocurred while cleaning optional permissions: ', err);
      });
}
