import {convertLanguages, isoLangs} from './consts';

export type TabOptionValue = ''|'yep'|'popup';
type DeprecatedTabOptionValue = 'panel';
type TabOptionValueIncludingDeprecated =
    TabOptionValue|DeprecatedTabOptionValue;

interface TabOption {
  value: TabOptionValue;
  labelMsg: string;
  deprecatedValues: TabOptionValueIncludingDeprecated[];
}

export interface TargetLangs {
  [key: string]: string;  // Here the key is a string with a number.
}
export interface OptionsV0 {
  translateinto: TargetLangs;
  uniquetab: TabOptionValue;
}

interface LegacyLanguages {
  [key: string]: string;  // Here the key is a string with the language code.
}
/**
 * Backwards-compatible interface for the information available in the sync
 * storage area.
 */
interface LegacyOptions {
  translateinto: TargetLangs;
  languages: LegacyLanguages;
  uniquetab: TabOptionValueIncludingDeprecated;
}

interface OptionsWrapper {
  options: OptionsV0;
  isFirstRun: boolean;
}

export const TAB_OPTIONS: TabOption[] = [
  // Open in new tab for each translation
  {
    value: '',
    labelMsg: 'options_tabsoption_1',
    deprecatedValues: [],
  },
  // Open in a unique tab
  {
    value: 'yep',
    labelMsg: 'options_tabsoption_2',
    deprecatedValues: [],
  },
  // Open in a popup
  {
    value: 'popup',
    labelMsg: 'options_tabsoption_3',
    deprecatedValues: ['panel'],
  },
];

// Class which can be used to retrieve the user options in order to act
// accordingly.
export default class Options {
  _options: OptionsV0;
  isFirstRun: boolean;

  constructor(options: OptionsV0, isFirstRun: boolean) {
    this._options = options;
    this.isFirstRun = isFirstRun;
  }

  get uniqueTab(): TabOptionValue {
    return this._options.uniquetab;
  }

  get targetLangs(): TargetLangs {
    return this._options.translateinto;
  }

  // Returns a promise that resolves in an instance of the Object class with the
  // current options.
  static getOptions(readOnly = true): Promise<Options> {
    return Options.getOptionsRaw(readOnly).then(res => {
      return new Options(res.options, res.isFirstRun);
    });
  }

  // Returns a promise that resolves to an object containing:
  // - |options|: normalized options object which can be used to initialize the
  // Options class, and which contains the current options set up by the user.
  // - |isFirstRun|: whether the extension is running for the first time and
  // needs to be set up.
  //
  // If the options needed to be normalized/created, they are also saved in the
  // sync storage area.
  static getOptionsRaw(readOnly: boolean): Promise<OptionsWrapper> {
    return new Promise((res, rej) => {
      chrome.storage.sync.get(null, itemsAny => {
        if (chrome.runtime.lastError) {
          return rej(chrome.runtime.lastError);
        }

        const items = <LegacyOptions>itemsAny;
        let didTranslateintoChange = false;
        let didUniquetabChange = false;

        // If the extension sync storage area is blank, set this as being the
        // first run.
        const isFirstRun = Object.keys(items).length === 0;

        // Create |translateinto| property if it doesn't exist.
        if (items.translateinto === undefined) {
          didTranslateintoChange = true;

          // Upgrade from a version previous to v0.7 if applicable, otherwise
          // create the property with the default values.
          if (items.languages !== undefined) {
            let newTranslateinto: TargetLangs;
            items.translateinto =
                Object.assign(newTranslateinto, Object.values(items.languages));
          } else {
            const uiLocale = chrome.i18n.getMessage('@@ui_locale');
            const defaultLang1 = uiLocale.replace('_', '-');
            const defaultLang2 = uiLocale.split('_')[0];

            items.translateinto = {};
            if (isoLangs[defaultLang1] != undefined)
              items.translateinto['0'] = defaultLang1;
            else if (isoLangs[defaultLang2] != undefined)
              items.translateinto['0'] = defaultLang2;
          }
        }

        // Normalize |translateinto| property: remove non-existent languages or
        // change them with the correct language code.
        for (const [index, language] of Object.entries(items.translateinto)) {
          if (isoLangs[language] === undefined) {
            didTranslateintoChange = true;
            if (convertLanguages[language] === undefined) {
              // The language doesn't exist
              console.log(
                  'Deleting ' + language +
                  ' from items.translateinto because it doesn\'t exist.');
              delete items.translateinto[index];
            } else {
              // The language doesn't exist but a known replacement is known
              const newLanguage = convertLanguages[language];
              console.log('Replacing ' + language + ' with ' + newLanguage);

              // If the converted language is already on the list, just remove
              // the wrong language, otherwise convert the language
              if (Object.values(items.translateinto).includes(newLanguage))
                delete items.translateinto[index];
              else
                items.translateinto[index] = newLanguage;
            }
          }
        }

        // Normalize |uniquetab| property:
        // - If it is set to a valid value, leave it alone.
        // - If it is set to a deprecated value, change it to the corresponding
        // value we use now.
        // - If it is set to an incorrect value or it isn't set, change it to
        // the default value.
        let uniquetabNewValue: TabOptionValue;
        let foundValue = false;
        for (const opt of TAB_OPTIONS) {
          if (opt.value == items?.uniquetab) {
            uniquetabNewValue = opt.value;
            foundValue = true;
            break;
          }
          if (opt.deprecatedValues.includes(items?.uniquetab)) {
            foundValue = true;
            uniquetabNewValue = opt.value;
            break;
          }
        }
        if (!foundValue) {
          uniquetabNewValue = 'popup';
          didUniquetabChange = true;
        }

        // Clean up deprecated properties
        if (items.languages !== undefined) {
          delete items.languages;
          chrome.storage.sync.remove('languages');
        }

        const returnObject: OptionsWrapper = {
          isFirstRun,
          options: {
            translateinto: items.translateinto,
            uniquetab: uniquetabNewValue,
          }
        };

        // Save properties that have changed if we're not in read-only mode
        if (!readOnly) {
          if (didTranslateintoChange || didUniquetabChange) {
            chrome.storage.sync.set(returnObject.options);
          }
        }

        res(returnObject);
      });
    });
  }
}
