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

import static com.android.settings.slices.CustomSliceRegistry.VOLUME_SLICES_URI;

import android.content.ContentProvider;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.net.Uri;
import android.util.ArrayMap;
import android.util.Log;

import androidx.annotation.VisibleForTesting;

import com.android.settingslib.SliceBroadcastRelay;

import java.util.Map;

/**
 * This helper is to handle the broadcasts of volume slices
 */
public class VolumeSliceHelper {

    private static final String TAG = "VolumeSliceHelper";

    @VisibleForTesting
    static Map<Uri, Integer> sRegisteredUri = new ArrayMap<>();
    @VisibleForTesting
    static IntentFilter sIntentFilter;

    static void registerIntentToUri(Context context, IntentFilter intentFilter, Uri sliceUri,
            int audioStream) {
        Log.d(TAG, "Registering uri for broadcast relay: " + sliceUri);
        synchronized (sRegisteredUri) {
            if (sRegisteredUri.isEmpty()) {
                SliceBroadcastRelay.registerReceiver(context, VOLUME_SLICES_URI,
                        VolumeSliceRelayReceiver.class, intentFilter);
                sIntentFilter = intentFilter;
            }
            sRegisteredUri.put(sliceUri, audioStream);
        }
    }

    static boolean unregisterUri(Context context, Uri sliceUri) {
        if (!sRegisteredUri.containsKey(sliceUri)) {
            return false;
        }

        Log.d(TAG, "Unregistering uri broadcast relay: " + sliceUri);
        synchronized (sRegisteredUri) {
            sRegisteredUri.remove(sliceUri);
            if (sRegisteredUri.isEmpty()) {
                sIntentFilter = null;
                SliceBroadcastRelay.unregisterReceivers(context, VOLUME_SLICES_URI);
            }
        }
        return true;
    }

    static void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();
        if (sIntentFilter == null || action == null || !sIntentFilter.hasAction(action)) {
            return;
        }

        final String uriString = intent.getStringExtra(SliceBroadcastRelay.EXTRA_URI);
        if (uriString == null) {
            return;
        }

        final Uri uri = Uri.parse(uriString);
        if (!VOLUME_SLICES_URI.equals(ContentProvider.getUriWithoutUserId(uri))) {
            Log.w(TAG, "Invalid uri: " + uriString);
            return;
        }

        if (AudioManager.VOLUME_CHANGED_ACTION.equals(action)) {
            handleVolumeChanged(context, intent);
        } else if (AudioManager.STREAM_MUTE_CHANGED_ACTION.equals(action)
                || AudioManager.STREAM_DEVICES_CHANGED_ACTION.equals(action)) {
            handleStreamChanged(context, intent);
        } else {
            notifyAllStreamsChanged(context);
        }
    }

    private static void handleVolumeChanged(Context context, Intent intent) {
        final int vol = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1);
        final int prevVol = intent.getIntExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, -1);
        if (vol != prevVol) {
            handleStreamChanged(context, intent);
        }
    }

    private static void handleStreamChanged(Context context, Intent intent) {
        final int inputType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
        for (Map.Entry<Uri, Integer> entry : sRegisteredUri.entrySet()) {
            if (entry.getValue() == inputType) {
                context.getContentResolver().notifyChange(entry.getKey(), null /* observer */);
                break;
            }
        }
    }

    private static void notifyAllStreamsChanged(Context context) {
        sRegisteredUri.forEach((uri, audioStream) -> {
            context.getContentResolver().notifyChange(uri, null /* observer */);
        });
    }
}
