/*
 * Copyright (C) 2015 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.server.telecom;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;

import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/** Listens for and caches car dock state. */
@VisibleForTesting
public class DockManager {
    @VisibleForTesting
    public interface Listener {
        void onDockChanged(boolean isDocked);
    }

    /** Receiver for car dock plugged and unplugged events. */
    private class DockBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.startSession("DM.oR");
            try {
                if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) {
                    int dockState = intent.getIntExtra(
                            Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_UNDOCKED);
                    onDockChanged(dockState);
                }
            } finally {
                Log.endSession();
            }
        }
    }

    private final DockBroadcastReceiver mReceiver;

    /**
     * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
     * load factor before resizing, 1 means we only expect a single thread to
     * access the map so make only a single shard
     */
    private final Set<Listener> mListeners = Collections.newSetFromMap(
            new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1));

    private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;

    DockManager(Context context) {
        mReceiver = new DockBroadcastReceiver();

        // Register for misc other intent broadcasts.
        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_DOCK_EVENT);
        context.registerReceiver(mReceiver, intentFilter);
    }

    @VisibleForTesting
    public void addListener(Listener listener) {
        mListeners.add(listener);
    }

    void removeListener(Listener listener) {
        if (listener != null) {
            mListeners.remove(listener);
        }
    }

    boolean isDocked() {
        switch (mDockState) {
            case Intent.EXTRA_DOCK_STATE_DESK:
            case Intent.EXTRA_DOCK_STATE_HE_DESK:
            case Intent.EXTRA_DOCK_STATE_LE_DESK:
            case Intent.EXTRA_DOCK_STATE_CAR:
                return true;
            default:
                return false;
        }
    }

    private void onDockChanged(int dockState) {
        if (mDockState != dockState) {
            Log.v(this, "onDockChanged: is docked?%b", dockState == Intent.EXTRA_DOCK_STATE_CAR);
            mDockState = dockState;
            for (Listener listener : mListeners) {
                listener.onDockChanged(isDocked());
            }
        }
    }

    /**
     * Dumps the state of the {@link DockManager}.
     *
     * @param pw The {@code IndentingPrintWriter} to write the state to.
     */
    public void dump(IndentingPrintWriter pw) {
        pw.println("mIsDocked: " + isDocked());
    }
}
