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

import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.om.OverlayManager;
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;

import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.SystemUI;

import com.google.android.collect.Sets;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.Map;
import java.util.Set;

/**
 * Controls the application of theme overlays across the system for all users.
 * This service is responsible for:
 * - Observing changes to Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES and applying the
 * corresponding overlays across the system
 * - Observing user switches, applying the overlays for the current user to user 0 (for systemui)
 * - Observing work profile changes and applying overlays from the primary user to their
 * associated work profiles
 */
public class ThemeOverlayController extends SystemUI {
    private static final String TAG = "ThemeOverlayController";
    private static final boolean DEBUG = false;

    private ThemeOverlayManager mThemeManager;
    private UserManager mUserManager;

    public ThemeOverlayController(Context context) {
        super(context);
    }

    @Override
    public void start() {
        if (DEBUG) Log.d(TAG, "Start");
        mUserManager = mContext.getSystemService(UserManager.class);
        mThemeManager = new ThemeOverlayManager(
                mContext.getSystemService(OverlayManager.class),
                AsyncTask.THREAD_POOL_EXECUTOR,
                mContext.getString(R.string.launcher_overlayable_package),
                mContext.getString(R.string.themepicker_overlayable_package));
        final Handler bgHandler = Dependency.get(Dependency.BG_HANDLER);
        final IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_USER_SWITCHED);
        filter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED);
        mContext.registerReceiverAsUser(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (DEBUG) Log.d(TAG, "Updating overlays for user switch / profile added.");
                updateThemeOverlays();
            }
        }, UserHandle.ALL, filter, null, bgHandler);
        mContext.getContentResolver().registerContentObserver(
                Settings.Secure.getUriFor(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES),
                false,
                new ContentObserver(bgHandler) {
                    @Override
                    public void onChange(boolean selfChange, Uri uri, int userId) {
                        if (DEBUG) Log.d(TAG, "Overlay changed for user: " + userId);
                        if (ActivityManager.getCurrentUser() == userId) {
                            updateThemeOverlays();
                        }
                    }
                },
                UserHandle.USER_ALL);
    }

    private void updateThemeOverlays() {
        final int currentUser = ActivityManager.getCurrentUser();
        final String overlayPackageJson = Settings.Secure.getStringForUser(
                mContext.getContentResolver(), Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
                currentUser);
        if (DEBUG) Log.d(TAG, "updateThemeOverlays: " + overlayPackageJson);
        final Map<String, String> categoryToPackage = new ArrayMap<>();
        if (!TextUtils.isEmpty(overlayPackageJson)) {
            try {
                JSONObject object = new JSONObject(overlayPackageJson);
                for (String category : ThemeOverlayManager.THEME_CATEGORIES) {
                    if (object.has(category)) {
                        categoryToPackage.put(category, object.getString(category));
                    }
                }
            } catch (JSONException e) {
                Log.i(TAG, "Failed to parse THEME_CUSTOMIZATION_OVERLAY_PACKAGES.", e);
            }
        }
        Set<UserHandle> userHandles = Sets.newHashSet(UserHandle.of(currentUser));
        for (UserInfo userInfo : mUserManager.getEnabledProfiles(currentUser)) {
            if (userInfo.isManagedProfile()) {
                userHandles.add(userInfo.getUserHandle());
            }
        }
        mThemeManager.applyCurrentUserOverlays(categoryToPackage, userHandles);
    }
}
