/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.customization.model.theme;

import static com.android.customization.model.ResourceConstants.ANDROID_PACKAGE;
import static com.android.customization.model.ResourceConstants.ICONS_FOR_PREVIEW;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_COLOR;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_FONT;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_ANDROID;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_LAUNCHER;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SETTINGS;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SYSUI;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_THEMEPICKER;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_SHAPE;
import static com.android.customization.model.ResourceConstants.SYSUI_PACKAGE;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources.NotFoundException;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.Nullable;

import com.android.customization.model.CustomizationManager.OptionsFetchedListener;
import com.android.customization.model.ResourcesApkProvider;
import com.android.customization.model.theme.ThemeBundle.Builder;
import com.android.customization.model.theme.ThemeBundle.PreviewInfo.ShapeAppIcon;
import com.android.customization.model.theme.custom.CustomTheme;
import com.android.customization.module.CustomizationPreferences;
import com.android.wallpaper.R;
import com.android.wallpaper.asset.ResourceAsset;

import com.bumptech.glide.request.RequestOptions;
import com.google.android.apps.wallpaper.asset.ThemeBundleThumbAsset;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Default implementation of {@link ThemeBundleProvider} that reads Themes' overlays from a stub APK.
 */
public class DefaultThemeProvider extends ResourcesApkProvider implements ThemeBundleProvider {

    private static final String TAG = "DefaultThemeProvider";

    private static final String THEMES_ARRAY = "themes";
    private static final String TITLE_PREFIX = "theme_title_";
    private static final String FONT_PREFIX = "theme_overlay_font_";
    private static final String COLOR_PREFIX = "theme_overlay_color_";
    private static final String SHAPE_PREFIX = "theme_overlay_shape_";
    private static final String ICON_ANDROID_PREFIX = "theme_overlay_icon_android_";
    private static final String ICON_LAUNCHER_PREFIX = "theme_overlay_icon_launcher_";
    private static final String ICON_THEMEPICKER_PREFIX = "theme_overlay_icon_themepicker_";
    private static final String ICON_SETTINGS_PREFIX = "theme_overlay_icon_settings_";
    private static final String ICON_SYSUI_PREFIX = "theme_overlay_icon_sysui_";

    private static final String DEFAULT_THEME_NAME= "default";
    private static final String THEME_TITLE_FIELD = "_theme_title";
    private static final String THEME_ID_FIELD = "_theme_id";

    private final OverlayThemeExtractor mOverlayProvider;
    private List<ThemeBundle> mThemes;
    private final CustomizationPreferences mCustomizationPreferences;

    public DefaultThemeProvider(Context context, CustomizationPreferences customizationPrefs) {
        super(context, context.getString(R.string.themes_stub_package));
        mOverlayProvider = new OverlayThemeExtractor(context);
        mCustomizationPreferences = customizationPrefs;
    }

    @Override
    public void fetch(OptionsFetchedListener<ThemeBundle> callback, boolean reload) {
        if (mThemes == null || reload) {
            mThemes = new ArrayList<>();
            loadAll();
        }

        if(callback != null) {
            callback.onOptionsLoaded(mThemes);
        }
    }

    @Override
    public boolean isAvailable() {
        return mOverlayProvider.isAvailable() && super.isAvailable();
    }

    private void loadAll() {
        // Add "Custom" option at the beginning.
        mThemes.add(new CustomTheme.Builder()
                .setId(CustomTheme.newId())
                .setTitle(mContext.getString(R.string.custom_theme))
                .build(mContext));

        addDefaultTheme();

        String[] themeNames = getItemsFromStub(THEMES_ARRAY);

        for (String themeName : themeNames) {
            // Default theme needs special treatment (see #addDefaultTheme())
            if (DEFAULT_THEME_NAME.equals(themeName)) {
                continue;
            }
            ThemeBundle.Builder builder = new Builder();
            try {
                builder.setTitle(mStubApkResources.getString(
                        mStubApkResources.getIdentifier(TITLE_PREFIX + themeName,
                                "string", mStubPackageName)));

                String shapeOverlayPackage = getOverlayPackage(SHAPE_PREFIX, themeName);
                mOverlayProvider.addShapeOverlay(builder, shapeOverlayPackage);

                String fontOverlayPackage = getOverlayPackage(FONT_PREFIX, themeName);
                mOverlayProvider.addFontOverlay(builder, fontOverlayPackage);

                String colorOverlayPackage = getOverlayPackage(COLOR_PREFIX, themeName);
                mOverlayProvider.addColorOverlay(builder, colorOverlayPackage);

                String iconAndroidOverlayPackage = getOverlayPackage(ICON_ANDROID_PREFIX,
                        themeName);

                mOverlayProvider.addAndroidIconOverlay(builder, iconAndroidOverlayPackage);

                String iconSysUiOverlayPackage = getOverlayPackage(ICON_SYSUI_PREFIX, themeName);

                mOverlayProvider.addSysUiIconOverlay(builder, iconSysUiOverlayPackage);

                String iconLauncherOverlayPackage = getOverlayPackage(ICON_LAUNCHER_PREFIX,
                        themeName);
                mOverlayProvider.addNoPreviewIconOverlay(builder, iconLauncherOverlayPackage);

                String iconThemePickerOverlayPackage = getOverlayPackage(ICON_THEMEPICKER_PREFIX,
                        themeName);
                mOverlayProvider.addNoPreviewIconOverlay(builder,
                        iconThemePickerOverlayPackage);

                String iconSettingsOverlayPackage = getOverlayPackage(ICON_SETTINGS_PREFIX,
                        themeName);

                mOverlayProvider.addNoPreviewIconOverlay(builder, iconSettingsOverlayPackage);

                mThemes.add(builder.build(mContext));
            } catch (NameNotFoundException | NotFoundException e) {
                Log.w(TAG, String.format("Couldn't load part of theme %s, will skip it", themeName),
                        e);
            }
        }

        addCustomThemes();
    }

    /**
     * Default theme requires different treatment: if there are overlay packages specified in the
     * stub apk, we'll use those, otherwise we'll get the System default values. But we cannot skip
     * the default theme.
     */
    private void addDefaultTheme() {
        ThemeBundle.Builder builder = new Builder().asDefault();

        int titleId = mStubApkResources.getIdentifier(TITLE_PREFIX + DEFAULT_THEME_NAME,
                "string", mStubPackageName);
        if (titleId > 0) {
            builder.setTitle(mStubApkResources.getString(titleId));
        } else {
            builder.setTitle(mContext.getString(R.string.default_theme_title));
        }

        String colorOverlayPackage = getOverlayPackage(COLOR_PREFIX, DEFAULT_THEME_NAME);

        try {
            mOverlayProvider.addColorOverlay(builder, colorOverlayPackage);
        } catch (NameNotFoundException | NotFoundException e) {
            Log.d(TAG, "Didn't find color overlay for default theme, will use system default");
            mOverlayProvider.addSystemDefaultColor(builder);
        }

        String fontOverlayPackage = getOverlayPackage(FONT_PREFIX, DEFAULT_THEME_NAME);

        try {
            mOverlayProvider.addFontOverlay(builder, fontOverlayPackage);
        } catch (NameNotFoundException | NotFoundException e) {
            Log.d(TAG, "Didn't find font overlay for default theme, will use system default");
            mOverlayProvider.addSystemDefaultFont(builder);
        }

        try {
            String shapeOverlayPackage = getOverlayPackage(SHAPE_PREFIX, DEFAULT_THEME_NAME);
            mOverlayProvider.addShapeOverlay(builder ,shapeOverlayPackage, false);
        } catch (NameNotFoundException | NotFoundException e) {
            Log.d(TAG, "Didn't find shape overlay for default theme, will use system default");
            mOverlayProvider.addSystemDefaultShape(builder);
        }

        List<ShapeAppIcon> icons = new ArrayList<>();
        for (String packageName : mOverlayProvider.getShapePreviewIconPackages()) {
            Drawable icon = null;
            CharSequence name = null;
            try {
                icon = mContext.getPackageManager().getApplicationIcon(packageName);
                ApplicationInfo appInfo = mContext.getPackageManager()
                        .getApplicationInfo(packageName, /* flag= */ 0);
                name = mContext.getPackageManager().getApplicationLabel(appInfo);
            } catch (NameNotFoundException e) {
                Log.d(TAG, "Couldn't find app " + packageName + ", won't use it for icon shape"
                        + "preview");
            } finally {
                if (icon != null && !TextUtils.isEmpty(name)) {
                    icons.add(new ShapeAppIcon(icon, name));
                }
            }
        }
        builder.setShapePreviewIcons(icons);

        try {
            String iconAndroidOverlayPackage = getOverlayPackage(ICON_ANDROID_PREFIX,
                    DEFAULT_THEME_NAME);
            mOverlayProvider.addAndroidIconOverlay(builder, iconAndroidOverlayPackage);
        } catch (NameNotFoundException | NotFoundException e) {
            Log.d(TAG, "Didn't find Android icons overlay for default theme, using system default");
            mOverlayProvider.addSystemDefaultIcons(builder, ANDROID_PACKAGE, ICONS_FOR_PREVIEW);
        }

        try {
            String iconSysUiOverlayPackage = getOverlayPackage(ICON_SYSUI_PREFIX,
                    DEFAULT_THEME_NAME);
            mOverlayProvider.addSysUiIconOverlay(builder, iconSysUiOverlayPackage);
        } catch (NameNotFoundException | NotFoundException e) {
            Log.d(TAG,
                    "Didn't find SystemUi icons overlay for default theme, using system default");
            mOverlayProvider.addSystemDefaultIcons(builder, SYSUI_PACKAGE, ICONS_FOR_PREVIEW);
        }

        mThemes.add(builder.build(mContext));
    }

    @Override
    public void storeCustomTheme(CustomTheme theme) {
        if (mThemes == null) {
            fetch(options -> {
                addCustomThemeAndStore(theme);
            }, false);
        } else {
            addCustomThemeAndStore(theme);
        }
    }

    private void addCustomThemeAndStore(CustomTheme theme) {
        if (!mThemes.contains(theme)) {
            mThemes.add(theme);
        } else {
            mThemes.replaceAll(t -> theme.equals(t) ? theme : t);
        }
        JSONArray themesArray = new JSONArray();
        mThemes.stream()
                .filter(themeBundle -> themeBundle instanceof CustomTheme
                        && !themeBundle.getPackagesByCategory().isEmpty())
                .forEachOrdered(themeBundle -> addThemeBundleToArray(themesArray, themeBundle));
        mCustomizationPreferences.storeCustomThemes(themesArray.toString());
    }

    private void addThemeBundleToArray(JSONArray themesArray, ThemeBundle themeBundle) {
        JSONObject jsonPackages = themeBundle.getJsonPackages(false);
        try {
            jsonPackages.put(THEME_TITLE_FIELD, themeBundle.getTitle());
            if (themeBundle instanceof CustomTheme) {
                jsonPackages.put(THEME_ID_FIELD, ((CustomTheme)themeBundle).getId());
            }
        } catch (JSONException e) {
            Log.w("Exception saving theme's title", e);
        }
        themesArray.put(jsonPackages);
    }

    @Override
    public void removeCustomTheme(CustomTheme theme) {
        JSONArray themesArray = new JSONArray();
        mThemes.stream()
                .filter(themeBundle -> themeBundle instanceof CustomTheme
                        && ((CustomTheme) themeBundle).isDefined())
                .forEachOrdered(customTheme -> {
                    if (!customTheme.equals(theme)) {
                        addThemeBundleToArray(themesArray, customTheme);
                    }
                });
        mCustomizationPreferences.storeCustomThemes(themesArray.toString());
    }

    private void addCustomThemes() {
        String serializedThemes = mCustomizationPreferences.getSerializedCustomThemes();
        int customThemesCount = 0;
        if (!TextUtils.isEmpty(serializedThemes)) {
            try {
                JSONArray customThemes = new JSONArray(serializedThemes);
                for (int i = 0; i < customThemes.length(); i++) {
                    JSONObject jsonTheme = customThemes.getJSONObject(i);
                    CustomTheme.Builder builder = new CustomTheme.Builder();
                    try {
                        convertJsonToBuilder(jsonTheme, builder);
                    } catch (NameNotFoundException | NotFoundException e) {
                        Log.i(TAG, "Couldn't parse serialized custom theme", e);
                        builder = null;
                    }
                    if (builder != null) {
                        if (TextUtils.isEmpty(builder.getTitle())) {
                            builder.setTitle(mContext.getString(R.string.custom_theme_title,
                                    customThemesCount + 1));
                        }
                        mThemes.add(builder.build(mContext));
                    } else {
                        Log.w(TAG, "Couldn't read stored custom theme, resetting");
                        mThemes.add(new CustomTheme.Builder()
                                .setId(CustomTheme.newId())
                                .setTitle(mContext.getString(
                                        R.string.custom_theme_title, customThemesCount + 1))
                                .build(mContext));
                    }
                    customThemesCount++;
                }
            } catch (JSONException e) {
                Log.w(TAG, "Couldn't read stored custom theme, resetting", e);
                mThemes.add(new CustomTheme.Builder()
                        .setId(CustomTheme.newId())
                        .setTitle(mContext.getString(
                                R.string.custom_theme_title, customThemesCount + 1))
                        .build(mContext));
            }
        }
    }

    @Nullable
    @Override
    public ThemeBundle.Builder parseThemeBundle(String serializedTheme) throws JSONException {
        JSONObject theme = new JSONObject(serializedTheme);
        try {
            ThemeBundle.Builder builder = new ThemeBundle.Builder();
            convertJsonToBuilder(theme, builder);
            return builder;
        } catch (NameNotFoundException | NotFoundException e) {
            Log.i(TAG, "Couldn't parse serialized custom theme", e);
            return null;
        }
    }

    @Nullable
    @Override
    public CustomTheme.Builder parseCustomTheme(String serializedTheme) throws JSONException {
        JSONObject theme = new JSONObject(serializedTheme);
        try {
            CustomTheme.Builder builder = new CustomTheme.Builder();
            convertJsonToBuilder(theme, builder);
            return builder;
        } catch (NameNotFoundException | NotFoundException e) {
            Log.i(TAG, "Couldn't parse serialized custom theme", e);
            return null;
        }
    }

    private void convertJsonToBuilder(JSONObject theme, ThemeBundle.Builder builder)
            throws JSONException, NameNotFoundException, NotFoundException {
        Map<String, String> customPackages = new HashMap<>();
        Iterator<String> keysIterator = theme.keys();

        while (keysIterator.hasNext()) {
            String category = keysIterator.next();
            customPackages.put(category, theme.getString(category));
        }
        mOverlayProvider.addShapeOverlay(builder,
                customPackages.get(OVERLAY_CATEGORY_SHAPE));
        mOverlayProvider.addFontOverlay(builder,
                customPackages.get(OVERLAY_CATEGORY_FONT));
        mOverlayProvider.addColorOverlay(builder,
                customPackages.get(OVERLAY_CATEGORY_COLOR));
        mOverlayProvider.addAndroidIconOverlay(builder,
                customPackages.get(OVERLAY_CATEGORY_ICON_ANDROID));
        mOverlayProvider.addSysUiIconOverlay(builder,
                customPackages.get(OVERLAY_CATEGORY_ICON_SYSUI));
        mOverlayProvider.addNoPreviewIconOverlay(builder,
                customPackages.get(OVERLAY_CATEGORY_ICON_SETTINGS));
        mOverlayProvider.addNoPreviewIconOverlay(builder,
                customPackages.get(OVERLAY_CATEGORY_ICON_LAUNCHER));
        mOverlayProvider.addNoPreviewIconOverlay(builder,
                customPackages.get(OVERLAY_CATEGORY_ICON_THEMEPICKER));
        if (theme.has(THEME_TITLE_FIELD)) {
            builder.setTitle(theme.getString(THEME_TITLE_FIELD));
        }
        if (builder instanceof CustomTheme.Builder && theme.has(THEME_ID_FIELD)) {
            ((CustomTheme.Builder) builder).setId(theme.getString(THEME_ID_FIELD));
        }
    }

    @Override
    public ThemeBundle findEquivalent(ThemeBundle other) {
        if (mThemes == null) {
            return null;
        }
        for (ThemeBundle theme : mThemes) {
            if (theme.isEquivalent(other)) {
                return theme;
            }
        }
        return null;
    }

    private String getOverlayPackage(String prefix, String themeName) {
        return getItemStringFromStub(prefix, themeName);
    }

    private ResourceAsset getDrawableResourceAsset(String prefix, String themeName) {
        int drawableResId = mStubApkResources.getIdentifier(prefix + themeName,
                "drawable", mStubPackageName);
        return drawableResId == 0 ? null : new ResourceAsset(mStubApkResources, drawableResId,
                RequestOptions.fitCenterTransform());
    }

    private ThemeBundleThumbAsset getThumbAsset(String prefix, String themeName) {
        int drawableResId = mStubApkResources.getIdentifier(prefix + themeName,
                "drawable", mStubPackageName);
        return drawableResId == 0 ? null : new ThemeBundleThumbAsset(mStubApkResources,
                drawableResId);
    }
}
