/*
 * Copyright (C) 2016 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.settings.widget;

import android.annotation.IdRes;
import android.annotation.UserIdInt;
import android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.support.annotation.IntDef;
import android.support.annotation.VisibleForTesting;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;

import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.applications.AppInfoBase;
import com.android.settings.applications.InstalledAppDetails;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.core.lifecycle.Lifecycle;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import static com.android.internal.logging.nano.MetricsProto.MetricsEvent
        .ACTION_OPEN_APP_NOTIFICATION_SETTING;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_OPEN_APP_SETTING;

public class EntityHeaderController {

    @IntDef({ActionType.ACTION_NONE,
            ActionType.ACTION_APP_PREFERENCE,
            ActionType.ACTION_NOTIF_PREFERENCE})
    @Retention(RetentionPolicy.SOURCE)
    public @interface ActionType {
        int ACTION_NONE = 0;
        int ACTION_APP_PREFERENCE = 1;
        int ACTION_NOTIF_PREFERENCE = 2;
    }

    public static final String PREF_KEY_APP_HEADER = "pref_app_header";

    private static final String TAG = "AppDetailFeature";

    private final Context mAppContext;
    private final Activity mActivity;
    private final Fragment mFragment;
    private final int mMetricsCategory;
    private final View mHeader;
    private Lifecycle mLifecycle;
    private RecyclerView mRecyclerView;
    private Drawable mIcon;
    private String mIconContentDescription;
    private CharSequence mLabel;
    private CharSequence mSummary;
    private String mPackageName;
    private Intent mAppNotifPrefIntent;
    @UserIdInt
    private int mUid = UserHandle.USER_NULL;
    @ActionType
    private int mAction1;
    @ActionType
    private int mAction2;

    private boolean mHasAppInfoLink;

    private boolean mIsInstantApp;

    /**
     * Creates a new instance of the controller.
     *
     * @param fragment The fragment that header will be placed in.
     * @param header   Optional: header view if it's already created.
     */
    public static EntityHeaderController newInstance(Activity activity, Fragment fragment,
            View header) {
        return new EntityHeaderController(activity, fragment, header);
    }

    private EntityHeaderController(Activity activity, Fragment fragment, View header) {
        mActivity = activity;
        mAppContext = activity.getApplicationContext();
        mFragment = fragment;
        mMetricsCategory = FeatureFactory.getFactory(mAppContext).getMetricsFeatureProvider()
                .getMetricsCategory(fragment);
        if (header != null) {
            mHeader = header;
        } else {
            mHeader = LayoutInflater.from(fragment.getContext())
                    .inflate(R.layout.settings_entity_header, null /* root */);
        }
    }

    public EntityHeaderController setRecyclerView(RecyclerView recyclerView, Lifecycle lifecycle) {
        mRecyclerView = recyclerView;
        mLifecycle = lifecycle;
        return this;
    }

    /**
     * Set the icon in the header. Callers should also consider calling setIconContentDescription
     * to provide a description of this icon for accessibility purposes.
     */
    public EntityHeaderController setIcon(Drawable icon) {
        if (icon != null) {
            mIcon = icon.getConstantState().newDrawable(mAppContext.getResources());
        }
        return this;
    }

    /**
     * Convenience method to set the header icon from an ApplicationsState.AppEntry. Callers should
     * also consider calling setIconContentDescription to provide a description of this icon for
     * accessibility purposes.
     */
    public EntityHeaderController setIcon(ApplicationsState.AppEntry appEntry) {
        if (appEntry.icon != null) {
            mIcon = appEntry.icon.getConstantState().newDrawable(mAppContext.getResources());
        }
        return this;
    }

    public EntityHeaderController setIconContentDescription(String contentDescription) {
        mIconContentDescription = contentDescription;
        return this;
    }

    public EntityHeaderController setLabel(CharSequence label) {
        mLabel = label;
        return this;
    }

    public EntityHeaderController setLabel(ApplicationsState.AppEntry appEntry) {
        mLabel = appEntry.label;
        return this;
    }

    public EntityHeaderController setSummary(CharSequence summary) {
        mSummary = summary;
        return this;
    }

    public EntityHeaderController setSummary(PackageInfo packageInfo) {
        if (packageInfo != null) {
            mSummary = packageInfo.versionName;
        }
        return this;
    }

    public EntityHeaderController setHasAppInfoLink(boolean hasAppInfoLink) {
        mHasAppInfoLink = hasAppInfoLink;
        return this;
    }

    public EntityHeaderController setButtonActions(@ActionType int action1,
            @ActionType int action2) {
        mAction1 = action1;
        mAction2 = action2;
        return this;
    }

    public EntityHeaderController setPackageName(String packageName) {
        mPackageName = packageName;
        return this;
    }

    public EntityHeaderController setUid(int uid) {
        mUid = uid;
        return this;
    }

    public EntityHeaderController setAppNotifPrefIntent(Intent appNotifPrefIntent) {
        mAppNotifPrefIntent = appNotifPrefIntent;
        return this;
    }

    public EntityHeaderController setIsInstantApp(boolean isInstantApp) {
        this.mIsInstantApp = isInstantApp;
        return this;
    }

    /**
     * Done mutating entity header, rebinds everything and return a new {@link LayoutPreference}.
     */
    public LayoutPreference done(Activity activity, Context uiContext) {
        final LayoutPreference pref = new LayoutPreference(uiContext, done(activity));
        // Makes sure it's the first preference onscreen.
        pref.setOrder(-1000);
        pref.setSelectable(false);
        pref.setKey(PREF_KEY_APP_HEADER);
        return pref;
    }

    /**
     * Done mutating entity header, rebinds everything (optionally skip rebinding buttons).
     */
    public View done(Activity activity, boolean rebindActions) {
        styleActionBar(activity);
        ImageView iconView = mHeader.findViewById(R.id.entity_header_icon);
        if (iconView != null) {
            iconView.setImageDrawable(mIcon);
            iconView.setContentDescription(mIconContentDescription);
        }
        setText(R.id.entity_header_title, mLabel);
        setText(R.id.entity_header_summary, mSummary);
        if (mIsInstantApp) {
            setText(R.id.install_type,
                    mHeader.getResources().getString(R.string.install_type_instant));
        }

        if (rebindActions) {
            bindHeaderButtons();
        }

        return mHeader;
    }

    /**
     * Only binds entity header with button actions.
     */
    public EntityHeaderController bindHeaderButtons() {
        final View entityHeaderContent = mHeader.findViewById(R.id.entity_header_content);
        final ImageButton button1 = mHeader.findViewById(android.R.id.button1);
        final ImageButton button2 = mHeader.findViewById(android.R.id.button2);
        bindAppInfoLink(entityHeaderContent);
        bindButton(button1, mAction1);
        bindButton(button2, mAction2);
        return this;
    }

    private void bindAppInfoLink(View entityHeaderContent) {
        if (!mHasAppInfoLink) {
            // Caller didn't ask for app link, skip.
            return;
        }
        if (entityHeaderContent == null
                || mPackageName == null
                || mPackageName.equals(Utils.OS_PKG)
                || mUid == UserHandle.USER_NULL) {
            Log.w(TAG, "Missing ingredients to build app info link, skip");
            return;
        }
        entityHeaderContent.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AppInfoBase.startAppInfoFragment(
                        InstalledAppDetails.class, R.string.application_info_label,
                        mPackageName, mUid, mFragment, 0 /* request */,
                        mMetricsCategory);

            }
        });
        return;
    }

    public EntityHeaderController styleActionBar(Activity activity) {
        if (activity == null) {
            Log.w(TAG, "No activity, cannot style actionbar.");
            return this;
        }
        final ActionBar actionBar = activity.getActionBar();
        if (actionBar == null) {
            Log.w(TAG, "No actionbar, cannot style actionbar.");
            return this;
        }
        actionBar.setBackgroundDrawable(
                new ColorDrawable(Utils.getColorAttr(activity, android.R.attr.colorSecondary)));
        actionBar.setElevation(0);
        if (mRecyclerView != null && mLifecycle != null) {
            ActionBarShadowController.attachToRecyclerView(mActivity, mLifecycle, mRecyclerView);
        }

        return this;
    }

    /**
     * Done mutating entity header, rebinds everything.
     */
    @VisibleForTesting
    View done(Activity activity) {
        return done(activity, true /* rebindActions */);
    }

    private void bindButton(ImageButton button, @ActionType int action) {
        if (button == null) {
            return;
        }
        switch (action) {
            case ActionType.ACTION_NOTIF_PREFERENCE: {
                if (mAppNotifPrefIntent == null) {
                    button.setVisibility(View.GONE);
                } else {
                    button.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            FeatureFactory.getFactory(mAppContext).getMetricsFeatureProvider()
                                    .actionWithSource(mAppContext, mMetricsCategory,
                                            ACTION_OPEN_APP_NOTIFICATION_SETTING);
                            mFragment.startActivity(mAppNotifPrefIntent);
                        }
                    });
                    button.setVisibility(View.VISIBLE);
                }
                return;
            }
            case ActionType.ACTION_APP_PREFERENCE: {
                final Intent intent = resolveIntent(
                        new Intent(Intent.ACTION_APPLICATION_PREFERENCES).setPackage(mPackageName));
                if (intent == null) {
                    button.setImageDrawable(null);
                    button.setVisibility(View.GONE);
                    return;
                }
                button.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        FeatureFactory.getFactory(mAppContext).getMetricsFeatureProvider()
                                .actionWithSource(mAppContext, mMetricsCategory,
                                        ACTION_OPEN_APP_SETTING);
                        mFragment.startActivity(intent);
                    }
                });
                button.setImageResource(R.drawable.ic_settings_24dp);
                button.setVisibility(View.VISIBLE);
                return;
            }
            case ActionType.ACTION_NONE: {
                button.setVisibility(View.GONE);
                return;
            }
        }
    }

    private Intent resolveIntent(Intent i) {
        ResolveInfo result = mAppContext.getPackageManager().resolveActivity(i, 0);
        if (result != null) {
            return new Intent(i.getAction())
                    .setClassName(result.activityInfo.packageName, result.activityInfo.name);
        }
        return null;
    }

    private void setText(@IdRes int id, CharSequence text) {
        TextView textView = mHeader.findViewById(id);
        if (textView != null) {
            textView.setText(text);
            textView.setVisibility(TextUtils.isEmpty(text) ? View.GONE : View.VISIBLE);
        }
    }
}
