import {grantedOptPermissions, isPermissionsObjectEmpty, missingPermissions} from './optionsPermissions.js';
import {optionsPrototype} from './optionsPrototype';
import specialOptions from './specialOptions.json5';

export {optionsPrototype, specialOptions};

// Adds missing options with their default value. If |dryRun| is set to false,
// they are also saved to the sync storage area.
export function cleanUpOptions(options, dryRun = false) {
  console.debug('[cleanUpOptions] Previous options', JSON.stringify(options));

  if (typeof options !== 'object' || options === null) options = {};

  var ok = true;
  for (const [opt, optMeta] of Object.entries(optionsPrototype)) {
    if (!(opt in options) &&
        optMeta['killSwitchType'] !== 'internalKillSwitch') {
      ok = false;
      options[opt] = optMeta['defaultValue'];
    }
  }

  console.debug('[cleanUpOptions] New options', JSON.stringify(options));

  if (!ok && !dryRun) {
    chrome.storage.sync.set(options);
  }

  return options;
}

// This piece of code is used as part of the getOptions computation, and so
// isn't that useful. It's exported since we sometimes need to finish the
// computation in a service worker, where we have access to the
// chrome.permissions API.
//
// It accepts as an argument an object |items| with the same structure of the
// items saved in the sync storage area, and an array |permissionChecksFeatures|
// of features
export function disableItemsWithMissingPermissions(
    items, permissionChecksFeatures) {
  return grantedOptPermissions().then(grantedPerms => {
    let permissionChecksPromises = [];
    for (const f of permissionChecksFeatures)
      permissionChecksPromises.push(missingPermissions(f, grantedPerms));

    Promise.all(permissionChecksPromises).then(missingPerms => {
      for (let i = 0; i < permissionChecksFeatures.length; i++)
        if (!isPermissionsObjectEmpty(missingPerms[i]))
          items[permissionChecksFeatures[i]] = false;

      return items;
    });
  });
}

// Returns a promise which returns the values of options |options| which are
// stored in the sync storage area.
//
// |requireOptionalPermissions| will determine whether to check if the required
// optional permissions have been granted or not to the options which have such
// requirements. If it is true, features with missing permissions will have
// their value set to false.
//
// When a kill switch is active, affected options always have their value set to
// false.

// #!if !production
let timerId = 0;
let randomId = btoa(Math.random().toString()).substr(10, 5);
// #!endif
export function getOptions(options, requireOptionalPermissions = true) {
  // #!if !production
  let timeLabel = 'getOptions--' + randomId + '-' + (timerId++);
  console.time(timeLabel);
  // #!endif
  // Once we only target MV3, this can be greatly simplified.
  return new Promise((resolve, reject) => {
           if (typeof options === 'string')
             options = [options, '_forceDisabledFeatures'];
           else if (Array.isArray(options))
             options = [...options, '_forceDisabledFeatures'];
           else if (options !== null)
             return reject(new Error(
                 'Unexpected |options| parameter of type ' + (typeof options) +
                 ' (expected: string, array, or null).'));

           chrome.storage.sync.get(options, items => {
             if (chrome.runtime.lastError)
               return reject(chrome.runtime.lastError);

             // Handle applicable kill switches which force disable features
             if (items?._forceDisabledFeatures) {
               for (let feature of items._forceDisabledFeatures) {
                 items[feature] = false;
               }

               delete items._forceDisabledFeatures;
             }

             if (!requireOptionalPermissions) return resolve(items);

             // Check whether some options have missing permissions which would
             // force disable these features
             let permissionChecksFeatures = [];
             for (const [key, value] of Object.entries(items))
               if ((key in optionsPrototype) && value &&
                   optionsPrototype[key].requiredOptPermissions?.length)
                 permissionChecksFeatures.push(key);

             if (permissionChecksFeatures.length == 0) return resolve(items);

             // If we don't have access to the chrome.permissions API (content
             // scripts don't have access to it[1]), do the final piece of
             // computation in the service worker/background script.
             // [1]:
             // https://developer.chrome.com/docs/extensions/mv3/content_scripts/

             // #!if !production
             console.debug(
                 'We are about to start checking granted permissions');
             console.timeLog(timeLabel);
             // #!endif
             if (!chrome.permissions) {
               return chrome.runtime.sendMessage(
                   {
                     message: 'runDisableItemsWithMissingPermissions',
                     options: {
                       items,
                       permissionChecksFeatures,
                     },
                   },
                   response => {
                     if (response === undefined)
                       return reject(new Error(
                           'An error ocurred while communicating with the service worker: ' +
                           chrome.runtime.lastError.message));

                     if (response.status == 'rejected')
                       return reject(response.error);
                     if (response.status == 'resolved')
                       return resolve(response.items);
                     return reject(new Error(
                         'An unknown response was recieved from service worker.'));
                   });
             }

             disableItemsWithMissingPermissions(items, permissionChecksFeatures)
                 .then(finalItems => resolve(finalItems))
                 .catch(err => reject(err));
           });
         })
      // #!if !production
      .then(items => {
        console.group('getOptions(options); resolved; options: ', options);
        console.timeEnd(timeLabel);
        console.groupEnd();
        return items;
      })
      .catch(err => {
        console.group('getOptions(options); rejected; options: ', options);
        console.timeEnd(timeLabel);
        console.groupEnd();
        throw err;
      })
      // #!endif
      ;
}

// Returns a promise which returns whether the |option| option/feature is
// currently enabled. If the feature requires optional permissions to work,
// |requireOptionalPermissions| will determine whether to check if the required
// optional permissions have been granted or not.
export function isOptionEnabled(option, requireOptionalPermissions = true) {
  return getOptions(option, requireOptionalPermissions).then(options => {
    return options?.[option] === true;
  });
}

export function getForceDisabledFeatures() {
  return new Promise((res, rej) => {
    chrome.storage.sync.get('_forceDisabledFeatures', items => {
      if (chrome.runtime.lastError) return rej(chrome.runtime.lastError);
      res(items?.['_forceDisabledFeatures'] ?? []);
    });
  });
}
