/*
 * 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.custom;

import static com.android.customization.model.ResourceConstants.ACCENT_COLOR_DARK_NAME;
import static com.android.customization.model.ResourceConstants.ACCENT_COLOR_LIGHT_NAME;
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_ANDROID_THEME;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_COLOR;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_ANDROID;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_SHAPE;
import static com.android.customization.model.ResourceConstants.PATH_SIZE;

import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.PathShape;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;

import androidx.core.graphics.PathParser;

import com.android.customization.model.ResourceConstants;
import com.android.customization.model.theme.OverlayManagerCompat;
import com.android.customization.model.theme.custom.ThemeComponentOption.ColorOption;
import com.android.wallpaper.R;

import java.util.ArrayList;
import java.util.List;

/**
 * Implementation of {@link ThemeComponentOptionProvider} that reads {@link ColorOption}s from
 * icon overlays.
 */
public class ColorOptionsProvider extends ThemeComponentOptionProvider<ColorOption> {

    private static final String TAG = "ColorOptionsProvider";
    private final CustomThemeManager mCustomThemeManager;
    private final String mDefaultThemePackage;

    public ColorOptionsProvider(Context context, OverlayManagerCompat manager,
            CustomThemeManager customThemeManager) {
        super(context, manager, OVERLAY_CATEGORY_COLOR);
        mCustomThemeManager = customThemeManager;
        // System color is set with a static overlay for android.theme category, so let's try to
        // find that first, and if that's not present, we'll default to System resources.
        // (see #addDefault())
        List<String> themePackages = manager.getOverlayPackagesForCategory(
                OVERLAY_CATEGORY_ANDROID_THEME, UserHandle.myUserId(), ANDROID_PACKAGE);
        mDefaultThemePackage = themePackages.isEmpty() ? null : themePackages.get(0);
    }

    @Override
    protected void loadOptions() {
        List<Drawable> previewIcons = new ArrayList<>();
        String iconPackage =
                mCustomThemeManager.getOverlayPackages().get(OVERLAY_CATEGORY_ICON_ANDROID);
        if (TextUtils.isEmpty(iconPackage)) {
            iconPackage = ANDROID_PACKAGE;
        }
        for (String iconName : ICONS_FOR_PREVIEW) {
            try {
                previewIcons.add(loadIconPreviewDrawable(iconName, iconPackage));
            } catch (NameNotFoundException | NotFoundException e) {
                Log.w(TAG, String.format("Couldn't load icon in %s for color preview, will skip it",
                        iconPackage), e);
            }
        }
        String shapePackage = mCustomThemeManager.getOverlayPackages().get(OVERLAY_CATEGORY_SHAPE);
        if (TextUtils.isEmpty(shapePackage)) {
            shapePackage = ANDROID_PACKAGE;
        }
        Drawable shape = loadShape(shapePackage);
        addDefault(previewIcons, shape);
        for (String overlayPackage : mOverlayPackages) {
            try {
                Resources overlayRes = getOverlayResources(overlayPackage);
                int lightColor = overlayRes.getColor(
                        overlayRes.getIdentifier(ACCENT_COLOR_LIGHT_NAME, "color", overlayPackage),
                        null);
                int darkColor = overlayRes.getColor(
                        overlayRes.getIdentifier(ACCENT_COLOR_DARK_NAME, "color", overlayPackage),
                        null);
                PackageManager pm = mContext.getPackageManager();
                String label = pm.getApplicationInfo(overlayPackage, 0).loadLabel(pm).toString();
                ColorOption option = new ColorOption(overlayPackage, label, lightColor, darkColor);
                option.setPreviewIcons(previewIcons);
                option.setShapeDrawable(shape);
                mOptions.add(option);
            } catch (NameNotFoundException | NotFoundException e) {
                Log.w(TAG, String.format("Couldn't load color overlay %s, will skip it",
                        overlayPackage), e);
            }
        }
    }

    private void addDefault(List<Drawable> previewIcons, Drawable shape) {
        int lightColor, darkColor;
        Resources system = Resources.getSystem();
        try {
            Resources r = getOverlayResources(mDefaultThemePackage);
            lightColor = r.getColor(
                    r.getIdentifier(ACCENT_COLOR_LIGHT_NAME, "color", mDefaultThemePackage),
                    null);
            darkColor = r.getColor(
                    r.getIdentifier(ACCENT_COLOR_DARK_NAME, "color", mDefaultThemePackage),
                    null);
        } catch (NotFoundException | NameNotFoundException e) {
            Log.d(TAG, "Didn't find default color, will use system option", e);

            lightColor = system.getColor(
                    system.getIdentifier(ACCENT_COLOR_LIGHT_NAME, "color", ANDROID_PACKAGE), null);

            darkColor = system.getColor(
                    system.getIdentifier(ACCENT_COLOR_DARK_NAME, "color", ANDROID_PACKAGE), null);
        }
        ColorOption option = new ColorOption(null,
                mContext.getString(R.string.default_theme_title), lightColor, darkColor);
        option.setPreviewIcons(previewIcons);
        option.setShapeDrawable(shape);
        mOptions.add(option);
    }

    private Drawable loadIconPreviewDrawable(String drawableName, String packageName)
            throws NameNotFoundException, NotFoundException {

        Resources overlayRes = getOverlayResources(packageName);
        return overlayRes.getDrawable(
                overlayRes.getIdentifier(drawableName, "drawable", packageName), null);
    }

    private Drawable loadShape(String packageName) {
        String path = null;
        try {
            Resources r = getOverlayResources(packageName);

            path = ResourceConstants.getIconMask(r, packageName);
        } catch (NameNotFoundException e) {
            Log.d(TAG, String.format("Couldn't load shape icon for %s, skipping.", packageName), e);
        }
        ShapeDrawable shapeDrawable = null;
        if (!TextUtils.isEmpty(path)) {
            PathShape shape = new PathShape(PathParser.createPathFromPathData(path),
                    PATH_SIZE, PATH_SIZE);
            shapeDrawable = new ShapeDrawable(shape);
            shapeDrawable.setIntrinsicHeight((int) PATH_SIZE);
            shapeDrawable.setIntrinsicWidth((int) PATH_SIZE);
        }
        return shapeDrawable;
    }

}
