/*
 * 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.systemui.qs.customize;

import android.Manifest.permission;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.provider.Settings;
import android.service.quicksettings.Tile;
import android.service.quicksettings.TileService;
import android.text.TextUtils;
import android.util.ArraySet;
import android.widget.Button;

import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.qs.QSTile.State;
import com.android.systemui.qs.QSTileHost;
import com.android.systemui.qs.dagger.QSScope;
import com.android.systemui.qs.external.CustomTile;
import com.android.systemui.qs.tileimpl.QSTileImpl.DrawableIcon;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.util.leak.GarbageMonitor;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Executor;

import javax.inject.Inject;

/** */
@QSScope
public class TileQueryHelper {
    private static final String TAG = "TileQueryHelper";

    private final ArrayList<TileInfo> mTiles = new ArrayList<>();
    private final ArraySet<String> mSpecs = new ArraySet<>();
    private final Executor mMainExecutor;
    private final Executor mBgExecutor;
    private final Context mContext;
    private final UserTracker mUserTracker;
    private TileStateListener mListener;

    private boolean mFinished;

    @Inject
    public TileQueryHelper(
            Context context,
            UserTracker userTracker,
            @Main Executor mainExecutor,
            @Background Executor bgExecutor
    ) {
        mContext = context;
        mMainExecutor = mainExecutor;
        mBgExecutor = bgExecutor;
        mUserTracker = userTracker;
    }

    public void setListener(TileStateListener listener) {
        mListener = listener;
    }

    public void queryTiles(QSTileHost host) {
        mTiles.clear();
        mSpecs.clear();
        mFinished = false;
        // Enqueue jobs to fetch every system tile and then ever package tile.
        addCurrentAndStockTiles(host);
    }

    public boolean isFinished() {
        return mFinished;
    }

    private void addCurrentAndStockTiles(QSTileHost host) {
        String stock = mContext.getString(R.string.quick_settings_tiles_stock);
        String current = Settings.Secure.getString(mContext.getContentResolver(),
                Settings.Secure.QS_TILES);
        final ArrayList<String> possibleTiles = new ArrayList<>();
        if (current != null) {
            // The setting QS_TILES is not populated immediately upon Factory Reset
            possibleTiles.addAll(Arrays.asList(current.split(",")));
        } else {
            current = "";
        }
        String[] stockSplit =  stock.split(",");
        for (String spec : stockSplit) {
            if (!current.contains(spec)) {
                possibleTiles.add(spec);
            }
        }
        if (Build.IS_DEBUGGABLE && !current.contains(GarbageMonitor.MemoryTile.TILE_SPEC)) {
            possibleTiles.add(GarbageMonitor.MemoryTile.TILE_SPEC);
        }

        final ArrayList<QSTile> tilesToAdd = new ArrayList<>();

        for (String spec : possibleTiles) {
            // Only add current and stock tiles that can be created from QSFactoryImpl.
            // Do not include CustomTile. Those will be created by `addPackageTiles`.
            if (spec.startsWith(CustomTile.PREFIX)) continue;
            final QSTile tile = host.createTile(spec);
            if (tile == null) {
                continue;
            } else if (!tile.isAvailable()) {
                tile.setTileSpec(spec);
                tile.destroy();
                continue;
            }
            tile.setTileSpec(spec);
            tilesToAdd.add(tile);
        }

        new TileCollector(tilesToAdd, host).startListening();
    }

    private static class TilePair {
        QSTile mTile;
        boolean mReady = false;
    }

    private class TileCollector implements QSTile.Callback {

        private final List<TilePair> mQSTileList = new ArrayList<>();
        private final QSTileHost mQSTileHost;

        TileCollector(List<QSTile> tilesToAdd, QSTileHost host) {
            for (QSTile tile: tilesToAdd) {
                TilePair pair = new TilePair();
                pair.mTile = tile;
                mQSTileList.add(pair);
            }
            mQSTileHost = host;
            if (tilesToAdd.isEmpty()) {
                mBgExecutor.execute(this::finished);
            }
        }

        private void finished() {
            notifyTilesChanged(false);
            addPackageTiles(mQSTileHost);
        }

        private void startListening() {
            for (TilePair pair: mQSTileList) {
                pair.mTile.addCallback(this);
                pair.mTile.setListening(this, true);
                // Make sure that at least one refresh state happens
                pair.mTile.refreshState();
            }
        }

        // This is called in the Bg thread
        @Override
        public void onStateChanged(State s) {
            boolean allReady = true;
            for (TilePair pair: mQSTileList) {
                if (!pair.mReady && pair.mTile.isTileReady()) {
                    pair.mTile.removeCallback(this);
                    pair.mTile.setListening(this, false);
                    pair.mReady = true;
                } else if (!pair.mReady) {
                    allReady = false;
                }
            }
            if (allReady) {
                for (TilePair pair : mQSTileList) {
                    QSTile tile = pair.mTile;
                    final QSTile.State state = tile.getState().copy();
                    // Ignore the current state and get the generic label instead.
                    state.label = tile.getTileLabel();
                    tile.destroy();
                    addTile(tile.getTileSpec(), null, state, true);
                }
                finished();
            }
        }

        @Override
        public void onShowDetail(boolean show) {}

        @Override
        public void onToggleStateChanged(boolean state) {}

        @Override
        public void onScanStateChanged(boolean state) {}

        @Override
        public void onAnnouncementRequested(CharSequence announcement) {}
    }

    private void addPackageTiles(final QSTileHost host) {
        mBgExecutor.execute(() -> {
            Collection<QSTile> params = host.getTiles();
            PackageManager pm = mContext.getPackageManager();
            List<ResolveInfo> services = pm.queryIntentServicesAsUser(
                    new Intent(TileService.ACTION_QS_TILE), 0, mUserTracker.getUserId());
            String stockTiles = mContext.getString(R.string.quick_settings_tiles_stock);

            for (ResolveInfo info : services) {
                String packageName = info.serviceInfo.packageName;
                ComponentName componentName = new ComponentName(packageName, info.serviceInfo.name);

                // Don't include apps that are a part of the default tile set.
                if (stockTiles.contains(componentName.flattenToString())) {
                    continue;
                }

                final CharSequence appLabel = info.serviceInfo.applicationInfo.loadLabel(pm);
                String spec = CustomTile.toSpec(componentName);
                State state = getState(params, spec);
                if (state != null) {
                    addTile(spec, appLabel, state, false);
                    continue;
                }
                if (info.serviceInfo.icon == 0 && info.serviceInfo.applicationInfo.icon == 0) {
                    continue;
                }
                Drawable icon = info.serviceInfo.loadIcon(pm);
                if (!permission.BIND_QUICK_SETTINGS_TILE.equals(info.serviceInfo.permission)) {
                    continue;
                }
                if (icon == null) {
                    continue;
                }
                icon.mutate();
                icon.setTint(mContext.getColor(android.R.color.white));
                CharSequence label = info.serviceInfo.loadLabel(pm);
                createStateAndAddTile(spec, icon, label != null ? label.toString() : "null",
                        appLabel);
            }

            notifyTilesChanged(true);
        });
    }

    private void notifyTilesChanged(final boolean finished) {
        final ArrayList<TileInfo> tilesToReturn = new ArrayList<>(mTiles);
        mMainExecutor.execute(() -> {
            if (mListener != null) {
                mListener.onTilesChanged(tilesToReturn);
            }
            mFinished = finished;
        });
    }

    private State getState(Collection<QSTile> tiles, String spec) {
        for (QSTile tile : tiles) {
            if (spec.equals(tile.getTileSpec())) {
                return tile.getState().copy();
            }
        }
        return null;
    }

    private void addTile(String spec, CharSequence appLabel, State state, boolean isSystem) {
        if (mSpecs.contains(spec)) {
            return;
        }
        TileInfo info = new TileInfo();
        info.state = state;
        info.state.dualTarget = false; // No dual targets in edit.
        info.state.expandedAccessibilityClassName =
                Button.class.getName();
        info.spec = spec;
        info.state.secondaryLabel = (isSystem || TextUtils.equals(state.label, appLabel))
                ? null : appLabel;
        info.isSystem = isSystem;
        mTiles.add(info);
        mSpecs.add(spec);
    }

    private void createStateAndAddTile(
            String spec, Drawable drawable, CharSequence label, CharSequence appLabel) {
        QSTile.State state = new QSTile.State();
        state.state = Tile.STATE_INACTIVE;
        state.label = label;
        state.contentDescription = label;
        state.icon = new DrawableIcon(drawable);
        addTile(spec, appLabel, state, false);
    }

    public static class TileInfo {
        public String spec;
        public QSTile.State state;
        public boolean isSystem;
    }

    public interface TileStateListener {
        void onTilesChanged(List<TileInfo> tiles);
    }
}
