/*
 * Copyright (C) 2015 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.notification;

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

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.Fragment;
import android.app.NotificationManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.service.notification.ZenModeConfig;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.utils.ZenServiceListing;

import java.lang.ref.WeakReference;
import java.text.Collator;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

public class ZenRuleSelectionDialog extends InstrumentedDialogFragment {
    private static final String TAG = "ZenRuleSelectionDialog";
    private static final boolean DEBUG = ZenModeSettings.DEBUG;

    private static ZenServiceListing mServiceListing;
    protected static PositiveClickListener mPositiveClickListener;

    private static Context mContext;
    private static PackageManager mPm;
    private static NotificationManager mNm;
    private LinearLayout mRuleContainer;

    /**
     * The interface we expect a listener to implement.
     */
    public interface PositiveClickListener {
        void onSystemRuleSelected(ZenRuleInfo ruleInfo, Fragment parent);
        void onExternalRuleSelected(ZenRuleInfo ruleInfo, Fragment parent);
    }

    @Override
    public int getMetricsCategory() {
        return MetricsEvent.NOTIFICATION_ZEN_MODE_RULE_SELECTION_DIALOG;
    }

    public static void show(Context context, Fragment parent, PositiveClickListener
            listener, ZenServiceListing serviceListing) {
        mPositiveClickListener = listener;
        mContext = context;
        mPm = mContext.getPackageManager();
        mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
        mServiceListing = serviceListing;

        ZenRuleSelectionDialog dialog = new ZenRuleSelectionDialog();
        dialog.setTargetFragment(parent, 0);
        dialog.show(parent.getFragmentManager(), TAG);
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        final View v = LayoutInflater.from(getContext()).inflate(R.layout.zen_rule_type_selection,
                null, false);

        mRuleContainer = (LinearLayout) v.findViewById(R.id.rule_container);
        if (mServiceListing != null) {
            bindType(defaultNewEvent());
            bindType(defaultNewSchedule());
            mServiceListing.addZenCallback(mServiceListingCallback);
            mServiceListing.reloadApprovedServices();
        }
        return new AlertDialog.Builder(getContext())
                .setTitle(R.string.zen_mode_choose_rule_type)
                .setView(v)
                .setNegativeButton(R.string.cancel, null)
                .create();
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        super.onDismiss(dialog);
        if (mServiceListing != null) {
            mServiceListing.removeZenCallback(mServiceListingCallback);
        }
    }

    private void bindType(final ZenRuleInfo ri) {
        try {
            ApplicationInfo info = mPm.getApplicationInfo(ri.packageName, 0);
            final LinearLayout v = (LinearLayout) LayoutInflater.from(mContext).inflate(
                    R.layout.zen_rule_type, null, false);

            ImageView iconView = v.findViewById(R.id.icon);
            ((TextView) v.findViewById(R.id.title)).setText(ri.title);
            if (!ri.isSystem) {
                LoadIconTask task = new LoadIconTask(iconView);
                task.execute(info);

                TextView subtitle = (TextView) v.findViewById(R.id.subtitle);
                subtitle.setText(info.loadLabel(mPm));
                subtitle.setVisibility(View.VISIBLE);
            } else {
                if (ZenModeConfig.isValidScheduleConditionId(ri.defaultConditionId)) {
                    iconView.setImageDrawable(mContext.getDrawable(R.drawable.ic_timelapse));
                } else if (ZenModeConfig.isValidEventConditionId(ri.defaultConditionId)) {
                    iconView.setImageDrawable(mContext.getDrawable(R.drawable.ic_event));
                }
            }
            v.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dismiss();
                    if (ri.isSystem) {
                        mPositiveClickListener.onSystemRuleSelected(ri, getTargetFragment());
                    } else {
                        mPositiveClickListener.onExternalRuleSelected(ri, getTargetFragment());
                    }
                }
            });
            mRuleContainer.addView(v);
        } catch (PackageManager.NameNotFoundException e) {
            // Omit rule.
        }
    }

    private ZenRuleInfo defaultNewSchedule() {
        final ZenModeConfig.ScheduleInfo schedule = new ZenModeConfig.ScheduleInfo();
        schedule.days = ZenModeConfig.ALL_DAYS;
        schedule.startHour = 22;
        schedule.endHour = 7;
        final ZenRuleInfo rt = new ZenRuleInfo();
        rt.settingsAction = ZenModeScheduleRuleSettings.ACTION;
        rt.title = mContext.getString(R.string.zen_schedule_rule_type_name);
        rt.packageName = ZenModeConfig.getEventConditionProvider().getPackageName();
        rt.defaultConditionId = ZenModeConfig.toScheduleConditionId(schedule);
        rt.serviceComponent = ZenModeConfig.getScheduleConditionProvider();
        rt.isSystem = true;
        return rt;
    }

    private ZenRuleInfo defaultNewEvent() {
        final ZenModeConfig.EventInfo event = new ZenModeConfig.EventInfo();
        event.calendar = null; // any calendar
        event.reply = ZenModeConfig.EventInfo.REPLY_ANY_EXCEPT_NO;
        final ZenRuleInfo rt = new ZenRuleInfo();
        rt.settingsAction = ZenModeEventRuleSettings.ACTION;
        rt.title = mContext.getString(R.string.zen_event_rule_type_name);
        rt.packageName = ZenModeConfig.getScheduleConditionProvider().getPackageName();
        rt.defaultConditionId = ZenModeConfig.toEventConditionId(event);
        rt.serviceComponent = ZenModeConfig.getEventConditionProvider();
        rt.isSystem = true;
        return rt;
    }

    private void bindExternalRules(Set<ZenRuleInfo> externalRuleTypes) {
        for (ZenRuleInfo ri : externalRuleTypes) {
            bindType(ri);
        }
    }

    private final ZenServiceListing.Callback mServiceListingCallback = new
            ZenServiceListing.Callback() {
        @Override
        public void onServicesReloaded(Set<ServiceInfo> services) {
            if (DEBUG) Log.d(TAG, "Services reloaded: count=" + services.size());
            Set<ZenRuleInfo> externalRuleTypes = new TreeSet<>(RULE_TYPE_COMPARATOR);
            for (ServiceInfo serviceInfo : services) {
                final ZenRuleInfo ri = AbstractZenModeAutomaticRulePreferenceController.
                        getRuleInfo(mPm, serviceInfo);
                if (ri != null && ri.configurationActivity != null
                        && mNm.isNotificationPolicyAccessGrantedForPackage(ri.packageName)
                        && (ri.ruleInstanceLimit <= 0 || ri.ruleInstanceLimit
                        >= (mNm.getRuleInstanceCount(serviceInfo.getComponentName()) + 1))) {
                    externalRuleTypes.add(ri);
                }
            }
            bindExternalRules(externalRuleTypes);
        }
    };

    private static final Comparator<ZenRuleInfo> RULE_TYPE_COMPARATOR =
            new Comparator<ZenRuleInfo>() {
                private final Collator mCollator = Collator.getInstance();

                @Override
                public int compare(ZenRuleInfo lhs, ZenRuleInfo rhs) {
                    int byAppName = mCollator.compare(lhs.packageLabel, rhs.packageLabel);
                    if (byAppName != 0) {
                        return byAppName;
                    } else {
                        return mCollator.compare(lhs.title, rhs.title);
                    }
                }
            };

    private class LoadIconTask extends AsyncTask<ApplicationInfo, Void, Drawable> {
        private final WeakReference<ImageView> viewReference;

        public LoadIconTask(ImageView view) {
            viewReference = new WeakReference<>(view);
        }

        @Override
        protected Drawable doInBackground(ApplicationInfo... params) {
            return params[0].loadIcon(mPm);
        }

        @Override
        protected void onPostExecute(Drawable icon) {
            if (icon != null) {
                final ImageView view = viewReference.get();
                if (view != null) {
                    view.setImageDrawable(icon);
                }
            }
        }
    }
}