/*
 * Copyright (C) 2018 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.car.settings.common;

import static com.android.settingslib.drawer.CategoryKey.CATEGORY_DEVICE;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE;

import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.text.TextUtils;

import androidx.preference.Preference;

import com.android.car.apps.common.util.Themes;
import com.android.car.settings.R;
import com.android.car.ui.preference.CarUiPreference;

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

/**
 * Loads Activity with TileUtils.EXTRA_SETTINGS_ACTION.
 */
// TODO: investigate using SettingsLib Tiles.
public class ExtraSettingsLoader {
    private static final Logger LOG = new Logger(ExtraSettingsLoader.class);
    private static final String META_DATA_PREFERENCE_CATEGORY = "com.android.settings.category";
    private Map<Preference, Bundle> mPreferenceBundleMap;
    private final Context mContext;

    public ExtraSettingsLoader(Context context) {
        mContext = context;
        mPreferenceBundleMap = new HashMap<>();
    }

    /**
     * Returns a map of {@link Preference} and {@link Bundle} representing settings injected from
     * system apps and their metadata. The given intent must specify the action to use for
     * resolving activities and a category with the key "com.android.settings.category" and one of
     * the values in {@link com.android.settingslib.drawer.CategoryKey}.
     *
     * @param intent intent specifying the extra settings category to load
     */
    public Map<Preference, Bundle> loadPreferences(Intent intent) {
        PackageManager pm = mContext.getPackageManager();
        List<ResolveInfo> results = pm.queryIntentActivitiesAsUser(intent,
                PackageManager.GET_META_DATA, ActivityManager.getCurrentUser());

        String extraCategory = intent.getStringExtra(META_DATA_PREFERENCE_CATEGORY);
        for (ResolveInfo resolved : results) {
            if (!resolved.system) {
                // Do not allow any app to be added to settings, only system ones.
                continue;
            }
            String title = null;
            String summary = null;
            String category = null;
            ActivityInfo activityInfo = resolved.activityInfo;
            Bundle metaData = activityInfo.metaData;
            try {
                Resources res = pm.getResourcesForApplication(activityInfo.packageName);
                if (metaData.containsKey(META_DATA_PREFERENCE_TITLE)) {
                    if (metaData.get(META_DATA_PREFERENCE_TITLE) instanceof Integer) {
                        title = res.getString(metaData.getInt(META_DATA_PREFERENCE_TITLE));
                    } else {
                        title = metaData.getString(META_DATA_PREFERENCE_TITLE);
                    }
                }
                if (TextUtils.isEmpty(title)) {
                    LOG.d("no title.");
                    title = activityInfo.loadLabel(pm).toString();
                }
                if (metaData.containsKey(META_DATA_PREFERENCE_SUMMARY)) {
                    if (metaData.get(META_DATA_PREFERENCE_SUMMARY) instanceof Integer) {
                        summary = res.getString(metaData.getInt(META_DATA_PREFERENCE_SUMMARY));
                    } else {
                        summary = metaData.getString(META_DATA_PREFERENCE_SUMMARY);
                    }
                } else {
                    LOG.d("no description.");
                }
                if (metaData.containsKey(META_DATA_PREFERENCE_CATEGORY)) {
                    if (metaData.get(META_DATA_PREFERENCE_CATEGORY) instanceof Integer) {
                        category = res.getString(metaData.getInt(META_DATA_PREFERENCE_CATEGORY));
                    } else {
                        category = metaData.getString(META_DATA_PREFERENCE_CATEGORY);
                    }
                } else {
                    LOG.d("no category.");
                }
            } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) {
                LOG.d("Couldn't find info", e);
            }
            Icon icon = null;
            if (metaData.containsKey(META_DATA_PREFERENCE_ICON)) {
                int iconRes = metaData.getInt(META_DATA_PREFERENCE_ICON);
                icon = Icon.createWithResource(activityInfo.packageName, iconRes);
            } else {
                icon = Icon.createWithResource(mContext, R.drawable.ic_settings_gear);
                LOG.d("use default icon.");
            }
            Intent extraSettingIntent =
                    new Intent().setClassName(activityInfo.packageName, activityInfo.name);
            if (category == null) {
                // If category is not specified or not supported, default to device.
                category = CATEGORY_DEVICE;
            }

            if (!TextUtils.equals(extraCategory, category)) {
                continue;
            }
            CarUiPreference preference = new CarUiPreference(mContext);
            preference.setTitle(title);
            preference.setSummary(summary);
            if (icon != null) {
                preference.setIcon(icon.loadDrawable(mContext));
                preference.getIcon().setTintList(
                        Themes.getAttrColorStateList(mContext, R.attr.iconColor));
            }
            preference.setIntent(extraSettingIntent);
            mPreferenceBundleMap.put(preference, metaData);
        }
        return mPreferenceBundleMap;
    }
}
