// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { loadTimeData } from '//resources/js/load_time_data.js';
/**
 * @fileoverview A browser proxy for fetching language settings.
 */
let instance = null;
const LAST_FETCH_SUPPORTED_LANGUAGES_TIME_KEY = 'lastFetchSupportedLanguagesTime';
const LAST_USED_SOURCE_LANGUAGE_KEY = 'lastUsedSourceLanguage';
const LAST_USED_TARGET_LANGUAGE_KEY = 'lastUsedTargetLanguage';
const RECENT_SOURCE_LANGUAGES_KEY = 'recentSourceLangauges';
const RECENT_TARGET_LANGAUGES_KEY = 'recentTargetLanguages';
const SUPPORTED_LANGUAGES_LOCALE_KEY = 'supportedLanguagesLocale';
const SUPPORTED_SOURCE_LANGUAGES_KEY = 'supportedSourceLanguages';
const SUPPORTED_TARGET_LANGUAGES_KEY = 'supportedTargetLanguages';
export class LanguageBrowserProxyImpl {
    static getInstance() {
        return instance || (instance = new LanguageBrowserProxyImpl());
    }
    static setInstance(obj) {
        instance = obj;
    }
    getClientLanguageList() {
        return chrome.languageSettingsPrivate.getLanguageList().then((clientLanguageList) => {
            return clientLanguageList.map(lang => ({
                languageCode: lang.code,
                name: lang.displayName,
            }));
        });
    }
    getLastUsedSourceLanguage() {
        return window.localStorage.getItem(LAST_USED_SOURCE_LANGUAGE_KEY);
    }
    getLastUsedTargetLanguage() {
        return window.localStorage.getItem(LAST_USED_TARGET_LANGUAGE_KEY);
    }
    getTranslateTargetLanguage() {
        return chrome.languageSettingsPrivate.getTranslateTargetLanguage();
    }
    getRecentSourceLanguages() {
        const sourceLanguagesJSON = window.localStorage.getItem(RECENT_SOURCE_LANGUAGES_KEY);
        if (!sourceLanguagesJSON) {
            return [];
        }
        return JSON.parse(sourceLanguagesJSON);
    }
    getRecentTargetLanguages() {
        const targetLanguagesJSON = window.localStorage.getItem(RECENT_TARGET_LANGAUGES_KEY);
        if (!targetLanguagesJSON) {
            return [];
        }
        return JSON.parse(targetLanguagesJSON);
    }
    getStoredServerLanguages(browserProxy) {
        if (this.shouldFetchSupportedLanguages()) {
            return browserProxy.handler.fetchSupportedLanguages().then(this.onServerLanguageListFetched.bind(this));
        }
        const sourceLangsJSON = window.localStorage.getItem(SUPPORTED_SOURCE_LANGUAGES_KEY);
        const targetLangsJSON = window.localStorage.getItem(SUPPORTED_TARGET_LANGUAGES_KEY);
        if (!sourceLangsJSON || !targetLangsJSON) {
            return Promise.resolve({ sourceLanguages: [], targetLanguages: [] });
        }
        const sourceLanguages = JSON.parse(sourceLangsJSON);
        const targetLanguages = JSON.parse(targetLangsJSON);
        return Promise.resolve({ sourceLanguages, targetLanguages });
    }
    storeLanguages(locale, sourceLanguages, targetLanguages) {
        window.localStorage.setItem(SUPPORTED_LANGUAGES_LOCALE_KEY, locale);
        window.localStorage.setItem(SUPPORTED_SOURCE_LANGUAGES_KEY, JSON.stringify(sourceLanguages));
        window.localStorage.setItem(SUPPORTED_TARGET_LANGUAGES_KEY, JSON.stringify(targetLanguages));
        window.localStorage.setItem(LAST_FETCH_SUPPORTED_LANGUAGES_TIME_KEY, Date.now().toString());
    }
    storeLastUsedSourceLanguage(sourceLanguageCode) {
        // If source language code is null, then it is likely set to 'auto'. We do
        // not need to store this value since it is default already.
        if (!sourceLanguageCode) {
            window.localStorage.removeItem(LAST_USED_SOURCE_LANGUAGE_KEY);
            return;
        }
        window.localStorage.setItem(LAST_USED_SOURCE_LANGUAGE_KEY, sourceLanguageCode);
    }
    storeLastUsedTargetLanguage(targetLanguageCode) {
        if (!targetLanguageCode) {
            return;
        }
        window.localStorage.setItem(LAST_USED_TARGET_LANGUAGE_KEY, targetLanguageCode);
    }
    storeRecentSourceLanguages(languages) {
        window.localStorage.setItem(RECENT_SOURCE_LANGUAGES_KEY, JSON.stringify(languages));
    }
    storeRecentTargetLanguages(languages) {
        window.localStorage.setItem(RECENT_TARGET_LANGAUGES_KEY, JSON.stringify(languages));
    }
    onServerLanguageListFetched(response) {
        if (response.sourceLanguages.length === 0 ||
            response.targetLanguages.length === 0) {
            return Promise.resolve({ sourceLanguages: [], targetLanguages: [] });
        }
        this.storeLanguages(response.browserLocale, response.sourceLanguages, response.targetLanguages);
        const sourceLanguages = response.sourceLanguages;
        const targetLanguages = response.targetLanguages;
        return Promise.resolve({ sourceLanguages, targetLanguages });
    }
    shouldFetchSupportedLanguages() {
        const languagesCacheTimeout = loadTimeData.getInteger('languagesCacheTimeout');
        const currentTimestamp = Date.now();
        const locale = window.localStorage.getItem(SUPPORTED_LANGUAGES_LOCALE_KEY);
        if (locale && !locale.startsWith(loadTimeData.getString('language'))) {
            return true;
        }
        // If there is no stored timestamp, we should fetch supported languages.
        const storedTimestampString = window.localStorage.getItem(LAST_FETCH_SUPPORTED_LANGUAGES_TIME_KEY);
        if (!storedTimestampString) {
            return true;
        }
        // If the stored timestamp is stored incorrectly, we need to fetch supported
        // languages.
        const storedTimestamp = parseInt(storedTimestampString);
        if (isNaN(storedTimestamp)) {
            return true;
        }
        // If the languages are not stored at all, we should also fetch supported
        // languages.
        const sourceLanguages = window.localStorage.getItem(SUPPORTED_SOURCE_LANGUAGES_KEY);
        const targetLanguages = window.localStorage.getItem(SUPPORTED_TARGET_LANGUAGES_KEY);
        if (!sourceLanguages || !targetLanguages) {
            return true;
        }
        // Finally, if the cache is to have expired, we should fetch supported
        // languages.
        const difference = currentTimestamp - storedTimestamp;
        return (difference / languagesCacheTimeout) >= 1;
    }
}
