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

import com.android.internal.telecom.IConnectionService;
import com.android.internal.telecom.IConnectionServiceAdapter;
import com.android.internal.telecom.IVideoProvider;
import com.android.internal.telecom.RemoteServiceCallback;

import junit.framework.TestCase;

import org.mockito.Mockito;

import android.content.ComponentName;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.IInterface;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.telecom.CallAudioState;
import android.telecom.Conference;
import android.telecom.Connection;
import android.telecom.ConnectionRequest;
import android.telecom.ConnectionService;
import android.telecom.DisconnectCause;
import android.telecom.Log;
import android.telecom.Logging.Session;
import android.telecom.ParcelableConference;
import android.telecom.ParcelableConnection;
import android.telecom.PhoneAccountHandle;
import android.telecom.StatusHints;
import android.telecom.TelecomManager;

import com.google.android.collect.Lists;

import java.lang.Override;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * Controls a test {@link IConnectionService} as would be provided by a source of connectivity
 * to the Telecom framework.
 */
public class ConnectionServiceFixture implements TestFixture<IConnectionService> {
    static int INVALID_VIDEO_STATE = -1;
    public CountDownLatch mExtrasLock = new CountDownLatch(1);
    static int NOT_SPECIFIED = 0;

    /**
     * Implementation of ConnectionService that performs no-ops for tasks normally meant for
     * Telephony and reports success back to Telecom
     */
    public class FakeConnectionServiceDelegate extends ConnectionService {
        int mVideoState = INVALID_VIDEO_STATE;
        int mCapabilities = NOT_SPECIFIED;
        int mProperties = NOT_SPECIFIED;

        @Override
        public Connection onCreateUnknownConnection(
                PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
            mLatestConnection = new FakeConnection(request.getVideoState(), request.getAddress());
            return mLatestConnection;
        }

        @Override
        public Connection onCreateIncomingConnection(
                PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
            FakeConnection fakeConnection =  new FakeConnection(
                    mVideoState == INVALID_VIDEO_STATE ? request.getVideoState() : mVideoState,
                    request.getAddress());
            mLatestConnection = fakeConnection;
            if (mCapabilities != NOT_SPECIFIED) {
                fakeConnection.setConnectionCapabilities(mCapabilities);
            }
            if (mProperties != NOT_SPECIFIED) {
                fakeConnection.setConnectionProperties(mProperties);
            }

            return fakeConnection;
        }

        @Override
        public Connection onCreateOutgoingConnection(
                PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
            FakeConnection fakeConnection = new FakeConnection(request.getVideoState(),
                    request.getAddress());
            mLatestConnection = fakeConnection;
            if (mCapabilities != NOT_SPECIFIED) {
                fakeConnection.setConnectionCapabilities(mCapabilities);
            }
            if (mProperties != NOT_SPECIFIED) {
                fakeConnection.setConnectionProperties(mProperties);
            }
            return fakeConnection;
        }

        @Override
        public void onCreateConnectionComplete(Connection connection) {
        }

        @Override
        public void onConference(Connection cxn1, Connection cxn2) {
            if (((FakeConnection) cxn1).getIsConferenceCreated()) {
                // Usually, this is implemented by something in Telephony, which does a bunch of
                // radio work to conference the two connections together. Here we just short-cut
                // that and declare them conferenced.
                Conference fakeConference = new FakeConference();
                fakeConference.addConnection(cxn1);
                fakeConference.addConnection(cxn2);
                mLatestConference = fakeConference;
                addConference(fakeConference);
            } else {
                try {
                    sendSetConferenceMergeFailed(cxn1.getTelecomCallId());
                } catch (Exception e) {
                    Log.w(this, "Exception on sendSetConferenceMergeFailed: " + e.getMessage());
                }
            }
        }
    }

    public class FakeConnection extends Connection {
        // Set to false if you wish the Conference merge to fail.
        boolean mIsConferenceCreated = true;

        public FakeConnection(int videoState, Uri address) {
            super();
            int capabilities = getConnectionCapabilities();
            capabilities |= CAPABILITY_MUTE;
            capabilities |= CAPABILITY_SUPPORT_HOLD;
            capabilities |= CAPABILITY_HOLD;
            setVideoState(videoState);
            setConnectionCapabilities(capabilities);
            setDialing();
            setAddress(address, TelecomManager.PRESENTATION_ALLOWED);
        }

        @Override
        public void onExtrasChanged(Bundle extras) {
            mExtrasLock.countDown();
        }

        public boolean getIsConferenceCreated() {
            return mIsConferenceCreated;
        }

        public void setIsConferenceCreated(boolean isConferenceCreated) {
            mIsConferenceCreated = isConferenceCreated;
        }
    }

    public class FakeConference extends Conference {
        public FakeConference() {
            super(null);
            setConnectionCapabilities(
                    Connection.CAPABILITY_SUPPORT_HOLD
                            | Connection.CAPABILITY_HOLD
                            | Connection.CAPABILITY_MUTE
                            | Connection.CAPABILITY_MANAGE_CONFERENCE);
        }

        @Override
        public void onMerge(Connection connection) {
            // Do nothing besides inform the connection that it was merged into this conference.
            connection.setConference(this);
        }

        @Override
        public void onExtrasChanged(Bundle extras) {
            Log.w(this, "FakeConference onExtrasChanged");
            mExtrasLock.countDown();
        }
    }

    public class FakeConnectionService extends IConnectionService.Stub {
        List<String> rejectedCallIds = Lists.newArrayList();

        @Override
        public void addConnectionServiceAdapter(IConnectionServiceAdapter adapter,
                Session.Info info) throws RemoteException {
            if (!mConnectionServiceAdapters.add(adapter)) {
                throw new RuntimeException("Adapter already added: " + adapter);
            }
            mConnectionServiceDelegateAdapter.addConnectionServiceAdapter(adapter,
                    null /*Session.Info*/);
        }

        @Override
        public void removeConnectionServiceAdapter(IConnectionServiceAdapter adapter,
                Session.Info info) throws RemoteException {
            if (!mConnectionServiceAdapters.remove(adapter)) {
                throw new RuntimeException("Adapter never added: " + adapter);
            }
            mConnectionServiceDelegateAdapter.removeConnectionServiceAdapter(adapter,
                    null /*Session.Info*/);
        }

        @Override
        public void createConnection(PhoneAccountHandle connectionManagerPhoneAccount,
                String id, ConnectionRequest request, boolean isIncoming, boolean isUnknown,
                Session.Info info) throws RemoteException {
            Log.i(ConnectionServiceFixture.this, "createConnection --> " + id);

            if (mConnectionById.containsKey(id)) {
                throw new RuntimeException("Connection already exists: " + id);
            }
            mLatestConnectionId = id;
            ConnectionInfo c = new ConnectionInfo();
            c.connectionManagerPhoneAccount = connectionManagerPhoneAccount;
            c.id = id;
            c.request = request;
            c.isIncoming = isIncoming;
            c.isUnknown = isUnknown;
            c.capabilities |= Connection.CAPABILITY_HOLD | Connection.CAPABILITY_SUPPORT_HOLD;
            c.videoState = request.getVideoState();
            c.mockVideoProvider = new MockVideoProvider();
            c.videoProvider = c.mockVideoProvider.getInterface();
            c.isConferenceCreated = true;
            mConnectionById.put(id, c);
            mConnectionServiceDelegateAdapter.createConnection(connectionManagerPhoneAccount,
                    id, request, isIncoming, isUnknown, null /*Session.Info*/);
        }

        @Override
        public void createConnectionComplete(String id, Session.Info info) throws RemoteException {
            mConnectionServiceDelegateAdapter.createConnectionComplete(id, null /*Session.Info*/);
        }

        @Override
        public void createConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount,
                String callId, ConnectionRequest request, boolean isIncoming,
                Session.Info sessionInfo) throws RemoteException {
            Log.i(ConnectionServiceFixture.this, "createConnectionFailed --> " + callId);

            if (mConnectionById.containsKey(callId)) {
                throw new RuntimeException("Connection already exists: " + callId);
            }

            // TODO(3p-calls): Implement this.
        }

        @Override
        public void abort(String callId, Session.Info info) throws RemoteException { }

        @Override
        public void answerVideo(String callId, int videoState,
                Session.Info info) throws RemoteException { }

        @Override
        public void answer(String callId, Session.Info info) throws RemoteException { }

        @Override
        public void reject(String callId, Session.Info info) throws RemoteException {
            rejectedCallIds.add(callId);
        }

        @Override
        public void rejectWithMessage(String callId, String message,
                Session.Info info) throws RemoteException { }

        @Override
        public void disconnect(String callId, Session.Info info) throws RemoteException { }

        @Override
        public void silence(String callId, Session.Info info) throws RemoteException { }

        @Override
        public void hold(String callId, Session.Info info) throws RemoteException { }

        @Override
        public void unhold(String callId, Session.Info info) throws RemoteException { }

        @Override
        public void onCallAudioStateChanged(String activeCallId, CallAudioState audioState,
                Session.Info info)
                throws RemoteException { }

        @Override
        public void playDtmfTone(String callId, char digit,
                Session.Info info) throws RemoteException { }

        @Override
        public void stopDtmfTone(String callId, Session.Info info) throws RemoteException { }

        @Override
        public void conference(String conferenceCallId, String callId,
                Session.Info info) throws RemoteException {
            mConnectionServiceDelegateAdapter.conference(conferenceCallId, callId, info);
        }

        @Override
        public void splitFromConference(String callId, Session.Info info) throws RemoteException { }

        @Override
        public void mergeConference(String conferenceCallId,
                Session.Info info) throws RemoteException { }

        @Override
        public void swapConference(String conferenceCallId,
                Session.Info info) throws RemoteException { }

        @Override
        public void onPostDialContinue(String callId, boolean proceed,
                Session.Info info) throws RemoteException { }

        @Override
        public void pullExternalCall(String callId, Session.Info info) throws RemoteException { }

        @Override
        public void sendCallEvent(String callId, String event, Bundle extras,
                Session.Info info) throws RemoteException
        {}

        public void onExtrasChanged(String callId, Bundle extras,
                Session.Info info) throws RemoteException {
            mConnectionServiceDelegateAdapter.onExtrasChanged(callId, extras, info);
        }

        @Override
        public void startRtt(String callId, ParcelFileDescriptor fromInCall,
                ParcelFileDescriptor toInCall, Session.Info sessionInfo) throws RemoteException {

        }

        @Override
        public void stopRtt(String callId, Session.Info sessionInfo) throws RemoteException {

        }

        @Override
        public void respondToRttUpgradeRequest(String callId, ParcelFileDescriptor fromInCall,
                ParcelFileDescriptor toInCall, Session.Info sessionInfo) throws RemoteException {

        }

        @Override
        public IBinder asBinder() {
            return this;
        }

        @Override
        public IInterface queryLocalInterface(String descriptor) {
            return this;
        }
    }

    FakeConnectionServiceDelegate mConnectionServiceDelegate =
            new FakeConnectionServiceDelegate();
    private IConnectionService mConnectionServiceDelegateAdapter =
            IConnectionService.Stub.asInterface(mConnectionServiceDelegate.onBind(null));

    FakeConnectionService mConnectionService = new FakeConnectionService();
    private IConnectionService.Stub mConnectionServiceSpy = Mockito.spy(mConnectionService);

    public class ConnectionInfo {
        PhoneAccountHandle connectionManagerPhoneAccount;
        String id;
        boolean ringing;
        ConnectionRequest request;
        boolean isIncoming;
        boolean isUnknown;
        int state;
        int addressPresentation;
        int capabilities;
        int properties;
        int supportedAudioRoutes;
        StatusHints statusHints;
        DisconnectCause disconnectCause;
        String conferenceId;
        String callerDisplayName;
        int callerDisplayNamePresentation;
        final List<String> conferenceableConnectionIds = new ArrayList<>();
        IVideoProvider videoProvider;
        Connection.VideoProvider videoProviderImpl;
        MockVideoProvider mockVideoProvider;
        int videoState;
        boolean isVoipAudioMode;
        Bundle extras;
        boolean isConferenceCreated;
    }

    public class ConferenceInfo {
        PhoneAccountHandle phoneAccount;
        int state;
        int capabilities;
        int properties;
        final List<String> connectionIds = new ArrayList<>();
        IVideoProvider videoProvider;
        int videoState;
        long connectTimeMillis;
        StatusHints statusHints;
        Bundle extras;
    }

    public String mLatestConnectionId;
    public Connection mLatestConnection;
    public Conference mLatestConference;
    public final Set<IConnectionServiceAdapter> mConnectionServiceAdapters = new HashSet<>();
    public final Map<String, ConnectionInfo> mConnectionById = new HashMap<>();
    public final Map<String, ConferenceInfo> mConferenceById = new HashMap<>();
    public final List<ComponentName> mRemoteConnectionServiceNames = new ArrayList<>();
    public final List<IBinder> mRemoteConnectionServices = new ArrayList<>();

    public ConnectionServiceFixture() throws Exception { }

    @Override
    public IConnectionService getTestDouble() {
        return mConnectionServiceSpy;
    }

    public void sendHandleCreateConnectionComplete(String id) throws Exception {
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.handleCreateConnectionComplete(
                    id,
                    mConnectionById.get(id).request,
                    parcelable(mConnectionById.get(id)), null /*Session.Info*/);
        }
    }

    public void sendSetActive(String id) throws Exception {
        mConnectionById.get(id).state = Connection.STATE_ACTIVE;
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.setActive(id, null /*Session.Info*/);
        }
    }

    public void sendSetRinging(String id) throws Exception {
        mConnectionById.get(id).state = Connection.STATE_RINGING;
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.setRinging(id, null /*Session.Info*/);
        }
    }

    public void sendSetDialing(String id) throws Exception {
        mConnectionById.get(id).state = Connection.STATE_DIALING;
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.setDialing(id, null /*Session.Info*/);
        }
    }

    public void sendSetDisconnected(String id, int disconnectCause) throws Exception {
        mConnectionById.get(id).state = Connection.STATE_DISCONNECTED;
        mConnectionById.get(id).disconnectCause = new DisconnectCause(disconnectCause);
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.setDisconnected(id, mConnectionById.get(id).disconnectCause, null /*Session.Info*/);
        }
    }

    public void sendSetOnHold(String id) throws Exception {
        mConnectionById.get(id).state = Connection.STATE_HOLDING;
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.setOnHold(id, null /*Session.Info*/);
        }
    }

    public void sendSetRingbackRequested(String id) throws Exception {
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.setRingbackRequested(id, mConnectionById.get(id).ringing, null /*Session.Info*/);
        }
    }

    public void sendSetConnectionCapabilities(String id) throws Exception {
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.setConnectionCapabilities(id, mConnectionById.get(id).capabilities,
                    null /*Session.Info*/);
        }
    }

    public void sendSetConnectionProperties(String id) throws Exception {
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.setConnectionProperties(id, mConnectionById.get(id).properties, null /*Session.Info*/);
        }
    }
    public void sendSetIsConferenced(String id) throws Exception {
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.setIsConferenced(id, mConnectionById.get(id).conferenceId, null /*Session.Info*/);
        }
    }

    public void sendAddConferenceCall(String id) throws Exception {
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.addConferenceCall(id, parcelable(mConferenceById.get(id)), null /*Session.Info*/);
        }
    }

    public void sendRemoveCall(String id) throws Exception {
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.removeCall(id, null /*Session.Info*/);
        }
    }

    public void sendOnPostDialWait(String id, String remaining) throws Exception {
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.onPostDialWait(id, remaining, null /*Session.Info*/);
        }
    }

    public void sendOnPostDialChar(String id, char nextChar) throws Exception {
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.onPostDialChar(id, nextChar, null /*Session.Info*/);
        }
    }

    public void sendQueryRemoteConnectionServices() throws Exception {
        mRemoteConnectionServices.clear();
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.queryRemoteConnectionServices(new RemoteServiceCallback.Stub() {
                @Override
                public void onError() throws RemoteException {
                    throw new RuntimeException();
                }

                @Override
                public void onResult(
                        List<ComponentName> names,
                        List<IBinder> services)
                        throws RemoteException {
                    TestCase.assertEquals(names.size(), services.size());
                    mRemoteConnectionServiceNames.addAll(names);
                    mRemoteConnectionServices.addAll(services);
                }

                @Override
                public IBinder asBinder() {
                    return this;
                }
            }, null /*Session.Info*/);
        }
    }

    public void sendSetVideoProvider(String id) throws Exception {
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.setVideoProvider(id, mConnectionById.get(id).videoProvider, null /*Session.Info*/);
        }
    }

    public void sendSetVideoState(String id) throws Exception {
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.setVideoState(id, mConnectionById.get(id).videoState, null /*Session.Info*/);
        }
    }

    public void sendSetIsVoipAudioMode(String id) throws Exception {
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.setIsVoipAudioMode(id, mConnectionById.get(id).isVoipAudioMode,
                    null /*Session.Info*/);
        }
    }

    public void sendSetStatusHints(String id) throws Exception {
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.setStatusHints(id, mConnectionById.get(id).statusHints, null /*Session.Info*/);
        }
    }

    public void sendSetAddress(String id) throws Exception {
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.setAddress(
                    id,
                    mConnectionById.get(id).request.getAddress(),
                    mConnectionById.get(id).addressPresentation, null /*Session.Info*/);
        }
    }

    public void sendSetCallerDisplayName(String id) throws Exception {
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.setCallerDisplayName(
                    id,
                    mConnectionById.get(id).callerDisplayName,
                    mConnectionById.get(id).callerDisplayNamePresentation, null /*Session.Info*/);
        }
    }

    public void sendSetConferenceableConnections(String id) throws Exception {
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.setConferenceableConnections(id, mConnectionById.get(id).conferenceableConnectionIds,
                    null /*Session.Info*/);
        }
    }

    public void sendAddExistingConnection(String id) throws Exception {
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.addExistingConnection(id, parcelable(mConnectionById.get(id)), null /*Session.Info*/);
        }
    }

    public void sendConnectionEvent(String id, String event, Bundle extras) throws Exception {
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.onConnectionEvent(id, event, extras, null /*Session.Info*/);
        }
    }

    public void sendSetConferenceMergeFailed(String id) throws Exception {
        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
            a.setConferenceMergeFailed(id, null /*Session.Info*/);
        }
    }

    /**
     * Waits until the {@link Connection#onExtrasChanged(Bundle)} API has been called on a
     * {@link Connection} or {@link Conference}.
     */
    public void waitForExtras() {
        try {
            mExtrasLock.await(TelecomSystemTest.TEST_TIMEOUT, TimeUnit.MILLISECONDS);
        } catch (InterruptedException ie) {
        }
        mExtrasLock = new CountDownLatch(1);
    }

    private ParcelableConference parcelable(ConferenceInfo c) {
        return new ParcelableConference(
                c.phoneAccount,
                c.state,
                c.capabilities,
                c.properties,
                c.connectionIds,
                c.videoProvider,
                c.videoState,
                c.connectTimeMillis,
                c.statusHints,
                c.extras);
    }

    private ParcelableConnection parcelable(ConnectionInfo c) {
        return new ParcelableConnection(
                c.request.getAccountHandle(),
                c.state,
                c.capabilities,
                c.properties,
                c.supportedAudioRoutes,
                c.request.getAddress(),
                c.addressPresentation,
                c.callerDisplayName,
                c.callerDisplayNamePresentation,
                c.videoProvider,
                c.videoState,
                false, /* ringback requested */
                false, /* voip audio mode */
                0, /* Connect Time for conf call on this connection */
                c.statusHints,
                c.disconnectCause,
                c.conferenceableConnectionIds,
                c.extras);
    }
}
