/*
 * 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 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 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);
    }
}
