/*
 * 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.statusbar.phone;

import android.app.ActivityManager;
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.UserInfo;
import android.os.UserHandle;
import android.os.UserManager;

import androidx.annotation.NonNull;

import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.SysUISingleton;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import javax.inject.Inject;

/**
 */
@SysUISingleton
public class ManagedProfileControllerImpl implements ManagedProfileController {

    private final List<Callback> mCallbacks = new ArrayList<>();

    private final Context mContext;
    private final UserManager mUserManager;
    private final BroadcastDispatcher mBroadcastDispatcher;
    private final LinkedList<UserInfo> mProfiles;
    private boolean mListening;
    private int mCurrentUser;

    /**
     */
    @Inject
    public ManagedProfileControllerImpl(Context context, BroadcastDispatcher broadcastDispatcher) {
        mContext = context;
        mUserManager = UserManager.get(mContext);
        mBroadcastDispatcher = broadcastDispatcher;
        mProfiles = new LinkedList<UserInfo>();
    }

    @Override
    public void addCallback(@NonNull Callback callback) {
        mCallbacks.add(callback);
        if (mCallbacks.size() == 1) {
            setListening(true);
        }
        callback.onManagedProfileChanged();
    }

    @Override
    public void removeCallback(@NonNull Callback callback) {
        if (mCallbacks.remove(callback) && mCallbacks.size() == 0) {
            setListening(false);
        }
    }

    public void setWorkModeEnabled(boolean enableWorkMode) {
        synchronized (mProfiles) {
            for (UserInfo ui : mProfiles) {
                if (!mUserManager.requestQuietModeEnabled(!enableWorkMode, UserHandle.of(ui.id))) {
                    StatusBarManager statusBarManager = (StatusBarManager) mContext
                            .getSystemService(android.app.Service.STATUS_BAR_SERVICE);
                    statusBarManager.collapsePanels();
                }
            }
        }
    }

    private void reloadManagedProfiles() {
        synchronized (mProfiles) {
            boolean hadProfile = mProfiles.size() > 0;
            int user = ActivityManager.getCurrentUser();
            mProfiles.clear();

            for (UserInfo ui : mUserManager.getEnabledProfiles(user)) {
                if (ui.isManagedProfile()) {
                    mProfiles.add(ui);
                }
            }
            if (mProfiles.size() == 0 && hadProfile && (user == mCurrentUser)) {
                for (Callback callback : mCallbacks) {
                    callback.onManagedProfileRemoved();
                }
            }
            mCurrentUser = user;
        }
    }

    public boolean hasActiveProfile() {
        if (!mListening) reloadManagedProfiles();
        synchronized (mProfiles) {
            return mProfiles.size() > 0;
        }
    }

    public boolean isWorkModeEnabled() {
        if (!mListening) reloadManagedProfiles();
        synchronized (mProfiles) {
            for (UserInfo ui : mProfiles) {
                if (ui.isQuietModeEnabled()) {
                    return false;
                }
            }
            return true;
        }
    }

    private void setListening(boolean listening) {
        mListening = listening;
        if (listening) {
            reloadManagedProfiles();

            final IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_USER_SWITCHED);
            filter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED);
            filter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED);
            filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
            filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
            mBroadcastDispatcher.registerReceiver(
                    mReceiver, filter, null /* handler */, UserHandle.ALL);
        } else {
            mBroadcastDispatcher.unregisterReceiver(mReceiver);
        }
    }

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            reloadManagedProfiles();
            for (Callback callback : mCallbacks) {
                callback.onManagedProfileChanged();
            }
        }
    };
}
