/*
 * Copyright (C) 2018 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.car.audio;

import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.car.media.CarAudioManager;
import android.content.pm.PackageManager;
import android.media.AudioAttributes;
import android.media.AudioFocusInfo;
import android.media.AudioManager;
import android.media.audiopolicy.AudioPolicy;
import android.os.Bundle;
import android.util.Log;

import com.android.car.CarLog;
import com.android.internal.util.Preconditions;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * Implements {@link AudioPolicy.AudioPolicyFocusListener}
 *
 * <p><b>Note:</b> Manages audio focus on a per zone basis.
 */
class CarZonesAudioFocus extends AudioPolicy.AudioPolicyFocusListener {

    private final boolean mDelayedFocusEnabled;
    private CarAudioService mCarAudioService; // Dynamically assigned just after construction
    private AudioPolicy mAudioPolicy; // Dynamically assigned just after construction

    private final Map<Integer, CarAudioFocus> mFocusZones = new HashMap<>();

    CarZonesAudioFocus(@NonNull AudioManager audioManager,
            @NonNull PackageManager packageManager,
            @NonNull CarAudioZone[] carAudioZones,
            @NonNull CarAudioSettings carAudioSettings,
            boolean enableDelayedAudioFocus) {
        //Create the zones here, the policy will be set setOwningPolicy,
        // which is called right after this constructor.
        Objects.requireNonNull(audioManager);
        Objects.requireNonNull(packageManager);
        Objects.requireNonNull(carAudioZones);
        Objects.requireNonNull(carAudioSettings);
        Preconditions.checkArgument(carAudioZones.length != 0,
                "There must be a minimum of one audio zone");

        //Create focus for all the zones
        for (CarAudioZone audioZone : carAudioZones) {
            int audioZoneId = audioZone.getId();
            if (Log.isLoggable(CarLog.TAG_AUDIO, Log.DEBUG)) {
                Log.d(CarLog.TAG_AUDIO,
                        "CarZonesAudioFocus adding new zone " + audioZoneId);
            }
            CarAudioFocus zoneFocusListener =
                    new CarAudioFocus(audioManager, packageManager,
                            new FocusInteraction(carAudioSettings), enableDelayedAudioFocus);
            mFocusZones.put(audioZoneId, zoneFocusListener);
        }
        mDelayedFocusEnabled = enableDelayedAudioFocus;
    }


    /**
     * Query the current list of focus loser in zoneId for uid
     * @param uid uid to query for current focus losers
     * @param zoneId zone id to query for info
     * @return list of current focus losers for uid
     */
    ArrayList<AudioFocusInfo> getAudioFocusLosersForUid(int uid, int zoneId) {
        CarAudioFocus focus = mFocusZones.get(zoneId);
        return focus.getAudioFocusLosersForUid(uid);
    }

    /**
     * Query the current list of focus holders in zoneId for uid
     * @param uid uid to query for current focus holders
     * @param zoneId zone id to query
     * @return list of current focus holders that for uid
     */
    ArrayList<AudioFocusInfo> getAudioFocusHoldersForUid(int uid, int zoneId) {
        CarAudioFocus focus = mFocusZones.get(zoneId);
        return focus.getAudioFocusHoldersForUid(uid);
    }

    /**
     * For each entry in list, transiently lose focus
     * @param afiList list of audio focus entries
     * @param zoneId zone id where focus should should be lost
     */
    void transientlyLoseInFocusInZone(@NonNull ArrayList<AudioFocusInfo> afiList,
            int zoneId) {
        CarAudioFocus focus = mFocusZones.get(zoneId);

        for (AudioFocusInfo info : afiList) {
            focus.removeAudioFocusInfoAndTransientlyLoseFocus(info);
        }
    }

    int reevaluateAndRegainAudioFocus(AudioFocusInfo afi) {
        CarAudioFocus focus = getFocusForAudioFocusInfo(afi);
        return focus.reevaluateAndRegainAudioFocus(afi);
    }


    /**
     * Sets the owning policy of the audio focus
     *
     * <p><b>Note:</b> This has to happen after the construction to avoid a chicken and egg
     * problem when setting up the AudioPolicy which must depend on this object.

     * @param carAudioService owning car audio service
     * @param parentPolicy owning parent car audio policy
     */
    void setOwningPolicy(CarAudioService carAudioService, AudioPolicy parentPolicy) {
        mAudioPolicy = parentPolicy;
        mCarAudioService = carAudioService;

        for (int zoneId : mFocusZones.keySet()) {
            mFocusZones.get(zoneId).setOwningPolicy(mAudioPolicy);
        }
    }

    @Override
    public void onAudioFocusRequest(AudioFocusInfo afi, int requestResult) {
        CarAudioFocus focus = getFocusForAudioFocusInfo(afi);
        focus.onAudioFocusRequest(afi, requestResult);
    }

    /**
     * @see AudioManager#abandonAudioFocus(AudioManager.OnAudioFocusChangeListener, AudioAttributes)
     * Note that we'll get this call for a focus holder that dies while in the focus stack, so
     * we don't need to watch for death notifications directly.
     */
    @Override
    public void onAudioFocusAbandon(AudioFocusInfo afi) {
        CarAudioFocus focus = getFocusForAudioFocusInfo(afi);
        focus.onAudioFocusAbandon(afi);
    }

    private CarAudioFocus getFocusForAudioFocusInfo(AudioFocusInfo afi) {
        //getFocusForAudioFocusInfo defaults to returning default zoneId
        //if uid has not been mapped, thus the value returned will be
        //default zone focus
        int zoneId = mCarAudioService.getZoneIdForUid(afi.getClientUid());

        // If the bundle attribute for AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID has been assigned
        // Use zone id from that instead.
        Bundle bundle = afi.getAttributes().getBundle();

        if (bundle != null) {
            int bundleZoneId =
                    bundle.getInt(CarAudioManager.AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID,
                            -1);
            // check if the zone id is within current zones bounds
            if (mCarAudioService.isAudioZoneIdValid(bundleZoneId)) {
                if (Log.isLoggable(CarLog.TAG_AUDIO, Log.DEBUG)) {
                    Log.d(CarLog.TAG_AUDIO,
                            "getFocusForAudioFocusInfo valid zoneId " + bundleZoneId
                                    + " with bundle request for client " + afi.getClientId());
                }
                zoneId = bundleZoneId;
            } else {
                Log.w(CarLog.TAG_AUDIO,
                        "getFocusForAudioFocusInfo invalid zoneId " + bundleZoneId
                                + " with bundle request for client " + afi.getClientId()
                                + ", dispatching focus request to zoneId " + zoneId);
            }
        }

        CarAudioFocus focus =  mFocusZones.get(zoneId);
        return focus;
    }

    /**
     * dumps the current state of the CarZoneAudioFocus
     *
     * @param indent indent to append to each new line
     * @param writer stream to write current state
     */
    void dump(String indent, PrintWriter writer) {
        writer.printf("%s*CarZonesAudioFocus*\n", indent);
        writer.printf("%s\tDelayed Focus Enabled: %b\n", indent, mDelayedFocusEnabled);
        writer.printf("%s\tCar Zones Audio Focus Listeners:\n", indent);
        Integer[] keys = mFocusZones.keySet().stream().sorted().toArray(Integer[]::new);
        for (Integer zoneId : keys) {
            writer.printf("%s\tZone Id: %s\n", indent, zoneId.toString());
            mFocusZones.get(zoneId).dump(indent + "\t", writer);
        }
    }

    public void updateUserForZoneId(int audioZoneId, @UserIdInt int userId) {
        Preconditions.checkArgument(mCarAudioService.isAudioZoneIdValid(audioZoneId),
                "Invalid zoneId %d", audioZoneId);
        mFocusZones.get(audioZoneId).getFocusInteraction().setUserIdForSettings(userId);
    }
}
