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

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.util.IconDrawableFactory;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.android.internal.app.AlertActivity;
import com.android.internal.app.AlertController;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;

import com.android.systemui.R;

import java.util.ArrayList;

/**
 * Show a list of currently running foreground services (supplied by the caller)
 * that the user can tap through to their application details.
 */
public final class ForegroundServicesDialog extends AlertActivity implements
        AdapterView.OnItemSelectedListener, DialogInterface.OnClickListener,
        AlertController.AlertParams.OnPrepareListViewListener {

    private static final String TAG = "ForegroundServicesDialog";

    LayoutInflater mInflater;

    private MetricsLogger mMetricsLogger;

    private String[] mPackages;
    private PackageItemAdapter mAdapter;

    private DialogInterface.OnClickListener mAppClickListener =
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    String pkg = mAdapter.getItem(which).packageName;
                    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                    intent.setData(Uri.fromParts("package", pkg, null));
                    startActivity(intent);
                    finish();
                }
            };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Dependency.initDependencies(getApplicationContext());

        mMetricsLogger = Dependency.get(MetricsLogger.class);

        mInflater = LayoutInflater.from(this);

        mAdapter = new PackageItemAdapter(this);

        final AlertController.AlertParams p = mAlertParams;
        p.mAdapter = mAdapter;
        p.mOnClickListener = mAppClickListener;
        p.mCustomTitleView = mInflater.inflate(R.layout.foreground_service_title, null);
        p.mIsSingleChoice = true;
        p.mOnItemSelectedListener = this;
        p.mPositiveButtonText = getString(com.android.internal.R.string.done_label);
        p.mPositiveButtonListener = this;
        p.mOnPrepareListViewListener = this;

        updateApps(getIntent());
        if (mPackages == null) {
            Log.w(TAG, "No packages supplied");
            finish();
            return;
        }

        setupAlert();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mMetricsLogger.visible(MetricsProto.MetricsEvent.RUNNING_BACKGROUND_APPS_DIALOG);
    }

    @Override
    protected void onPause() {
        super.onPause();
        mMetricsLogger.hidden(MetricsProto.MetricsEvent.RUNNING_BACKGROUND_APPS_DIALOG);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        updateApps(intent);
    }

    @Override
    protected void onStop() {
        super.onStop();

        // This is a transient dialog, if the user leaves it then it goes away,
        // they can return back to it from the notification.
        if (!isChangingConfigurations()) {
            finish();
        }
    }

    void updateApps(Intent intent) {
        mPackages = intent.getStringArrayExtra("packages");
        if (mPackages != null) {
            mAdapter.setPackages(mPackages);
        }
    }

    public void onPrepareListView(ListView listView) {
    }

    /*
     * On click of Ok/Cancel buttons
     */
    public void onClick(DialogInterface dialog, int which) {
        finish();
    }

    public void onItemSelected(AdapterView parent, View view, int position, long id) {
    }

    public void onNothingSelected(AdapterView parent) {
    }

    static private class PackageItemAdapter extends ArrayAdapter<ApplicationInfo> {
        final PackageManager mPm;
        final LayoutInflater mInflater;
        final IconDrawableFactory mIconDrawableFactory;

        public PackageItemAdapter(Context context) {
            super(context, R.layout.foreground_service_item);
            mPm = context.getPackageManager();
            mInflater = LayoutInflater.from(context);
            mIconDrawableFactory = IconDrawableFactory.newInstance(context, true);
        }

        public void setPackages(String[] packages) {
            clear();

            ArrayList<ApplicationInfo> apps = new ArrayList<>();
            for (int i = 0; i < packages.length; i++) {
                try {
                    apps.add(mPm.getApplicationInfo(packages[i],
                            PackageManager.MATCH_KNOWN_PACKAGES));
                } catch (PackageManager.NameNotFoundException e) {
                }
            }

            apps.sort(new ApplicationInfo.DisplayNameComparator(mPm));
            addAll(apps);
        }

        public @NonNull
        View getView(int position, @Nullable View convertView,
                @NonNull ViewGroup parent) {
            final View view;
            if (convertView == null) {
                view = mInflater.inflate(R.layout.foreground_service_item, parent, false);
            } else {
                view = convertView;
            }

            ImageView icon = view.findViewById(R.id.app_icon);
            icon.setImageDrawable(mIconDrawableFactory.getBadgedIcon(getItem(position)));

            TextView label = view.findViewById(R.id.app_name);
            label.setText(getItem(position).loadLabel(mPm));

            return view;
        }
    }
}
