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

// Required permissions, including host permissions.
//
// IMPORTANT: This should be kept in sync with the "permissions" key in
// //templates/manifest.gjson.
const requiredPermissions = new Set([
  'storage',
  'alarms',
]);

// 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 an array of optional permissions needed by all
// the current enabled features.
export function currentRequiredOptPermissions() {
  return getOptions(null, /* requireOptionalPermissions = */ false)
      .then(options => {
        let 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
            permissions.push(...(optMeta.requiredOptPermissions ?? []));

        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 list of 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 =
          response.permissions.filter(p => !requiredPermissions.has(p));
      resolve(optPermissions);
    });
  });
}

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

// Returns a promise which resolves to the array of required optional
// permissions of |feature| which are missing.
//
// Accepts an argument |grantedPermissions| with the array of 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 => {
        return perms[1].filter(p => !perms[0].includes(p));
      })
      .catch(cause => {
        throw new Error(
            'Couldn\'t compute the missing permissions for "' + feature + '",',
            {cause});
      });
}

// 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 (missingPermissions.length > 0) {
          actionApi.setBadgeBackgroundColor({color: '#B71C1C'});
          actionApi.setBadgeText({text: '!'});
          // This is to work around https://crbug.com/1268098.
          // TODO(avm99963): Remove when the bug is fixed.
          // #!if browser_target !== 'chromium_mv3'
          actionApi.setTitle({
            title: chrome.i18n.getMessage('actionbadge_permissions_requested')
          });
          // #!endif
        } else {
          actionApi.setBadgeText({text: ''});
          actionApi.setTitle({title: ''});
        }

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