/*
 * Copyright (C) 2014 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 com.android.internal.annotations.VisibleForTesting;
import com.android.server.telecom.bluetooth.BluetoothDeviceManager;
import com.android.server.telecom.bluetooth.BluetoothRouteManager;
import com.android.server.telecom.bluetooth.BluetoothStateReceiver;
import com.android.server.telecom.components.UserCallIntentProcessor;
import com.android.server.telecom.components.UserCallIntentProcessorFactory;
import com.android.server.telecom.ui.AudioProcessingNotification;
import com.android.server.telecom.ui.DisconnectedCallNotifier;
import com.android.server.telecom.ui.IncomingCallNotifier;
import com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory;
import com.android.server.telecom.CallAudioManager.AudioServiceFactory;
import com.android.server.telecom.DefaultDialerCache.DefaultDialerManagerAdapter;
import com.android.server.telecom.ui.ToastFactory;

import android.app.ActivityManager;
import android.bluetooth.BluetoothManager;
import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.UserHandle;
import android.os.UserManager;
import android.telecom.Log;
import android.telecom.PhoneAccountHandle;
import android.widget.Toast;

import androidx.annotation.NonNull;

import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.List;

/**
 * Top-level Application class for Telecom.
 */
public class TelecomSystem {

    /**
     * This interface is implemented by system-instantiated components (e.g., Services and
     * Activity-s) that wish to use the TelecomSystem but would like to be testable. Such a
     * component should implement the getTelecomSystem() method to return the global singleton,
     * and use its own method. Tests can subclass the component to return a non-singleton.
     *
     * A refactoring goal for Telecom is to limit use of the TelecomSystem singleton to those
     * system-instantiated components, and have all other parts of the system just take all their
     * dependencies as explicit arguments to their constructor or other methods.
     */
    public interface Component {
        TelecomSystem getTelecomSystem();
    }


    /**
     * Tagging interface for the object used for synchronizing multi-threaded operations in
     * the Telecom system.
     */
    public interface SyncRoot {
    }

    private static final IntentFilter USER_SWITCHED_FILTER =
            new IntentFilter(Intent.ACTION_USER_SWITCHED);

    private static final IntentFilter USER_STARTING_FILTER =
            new IntentFilter(Intent.ACTION_USER_STARTING);

    private static final IntentFilter BOOT_COMPLETE_FILTER =
            new IntentFilter(Intent.ACTION_BOOT_COMPLETED);

    /** Intent filter for dialer secret codes. */
    private static final IntentFilter DIALER_SECRET_CODE_FILTER;

    /**
     * Initializes the dialer secret code intent filter.  Setup to handle the various secret codes
     * which can be dialed (e.g. in format *#*#code#*#*) to trigger various behavior in Telecom.
     */
    static {
        DIALER_SECRET_CODE_FILTER = new IntentFilter(
                "android.provider.Telephony.SECRET_CODE");
        DIALER_SECRET_CODE_FILTER.addDataScheme("android_secret_code");
        DIALER_SECRET_CODE_FILTER
                .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_ON, null);
        DIALER_SECRET_CODE_FILTER
                .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_OFF, null);
        DIALER_SECRET_CODE_FILTER
                .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_MARK, null);
        DIALER_SECRET_CODE_FILTER
                .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_MENU, null);
    }

    private static TelecomSystem INSTANCE = null;

    private final SyncRoot mLock = new SyncRoot() { };
    private final MissedCallNotifier mMissedCallNotifier;
    private final IncomingCallNotifier mIncomingCallNotifier;
    private final PhoneAccountRegistrar mPhoneAccountRegistrar;
    private final CallsManager mCallsManager;
    private final RespondViaSmsManager mRespondViaSmsManager;
    private final Context mContext;
    private final CallIntentProcessor mCallIntentProcessor;
    private final TelecomBroadcastIntentProcessor mTelecomBroadcastIntentProcessor;
    private final TelecomServiceImpl mTelecomServiceImpl;
    private final ContactsAsyncHelper mContactsAsyncHelper;
    private final DialerCodeReceiver mDialerCodeReceiver;

    private boolean mIsBootComplete = false;

    private final BroadcastReceiver mUserSwitchedReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.startSession("TSSwR.oR");
            try {
                synchronized (mLock) {
                    int userHandleId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
                    UserHandle currentUserHandle = new UserHandle(userHandleId);
                    mPhoneAccountRegistrar.setCurrentUserHandle(currentUserHandle);
                    mCallsManager.onUserSwitch(currentUserHandle);
                }
            } finally {
                Log.endSession();
            }
        }
    };

    private final BroadcastReceiver mUserStartingReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.startSession("TSStR.oR");
            try {
                synchronized (mLock) {
                    int userHandleId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
                    UserHandle addingUserHandle = new UserHandle(userHandleId);
                    mCallsManager.onUserStarting(addingUserHandle);
                }
            } finally {
                Log.endSession();
            }
        }
    };

    private final BroadcastReceiver mBootCompletedReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.startSession("TSBCR.oR");
            try {
                synchronized (mLock) {
                    mIsBootComplete = true;
                    mCallsManager.onBootCompleted();
                }
            } finally {
                Log.endSession();
            }
        }
    };

    public static TelecomSystem getInstance() {
        return INSTANCE;
    }

    public static void setInstance(TelecomSystem instance) {
        if (INSTANCE != null) {
            Log.w("TelecomSystem", "Attempt to set TelecomSystem.INSTANCE twice");
        }
        Log.i(TelecomSystem.class, "TelecomSystem.INSTANCE being set");
        INSTANCE = instance;
    }

    public TelecomSystem(
            Context context,
            MissedCallNotifierImplFactory missedCallNotifierImplFactory,
            CallerInfoAsyncQueryFactory callerInfoAsyncQueryFactory,
            HeadsetMediaButtonFactory headsetMediaButtonFactory,
            ProximitySensorManagerFactory proximitySensorManagerFactory,
            InCallWakeLockControllerFactory inCallWakeLockControllerFactory,
            AudioServiceFactory audioServiceFactory,
            ConnectionServiceFocusManager.ConnectionServiceFocusManagerFactory
                    connectionServiceFocusManagerFactory,
            Timeouts.Adapter timeoutsAdapter,
            AsyncRingtonePlayer asyncRingtonePlayer,
            PhoneNumberUtilsAdapter phoneNumberUtilsAdapter,
            IncomingCallNotifier incomingCallNotifier,
            InCallTonePlayer.ToneGeneratorFactory toneGeneratorFactory,
            CallAudioRouteStateMachine.Factory callAudioRouteStateMachineFactory,
            CallAudioModeStateMachine.Factory callAudioModeStateMachineFactory,
            ClockProxy clockProxy,
            RoleManagerAdapter roleManagerAdapter,
            ContactsAsyncHelper.Factory contactsAsyncHelperFactory,
            DeviceIdleControllerAdapter deviceIdleControllerAdapter) {
        mContext = context.getApplicationContext();
        LogUtils.initLogging(mContext);
        DefaultDialerManagerAdapter defaultDialerAdapter =
                new DefaultDialerCache.DefaultDialerManagerAdapterImpl();

        DefaultDialerCache defaultDialerCache = new DefaultDialerCache(mContext,
                defaultDialerAdapter, roleManagerAdapter, mLock);

        Log.startSession("TS.init");
        // Wrap this in a try block to ensure session cleanup occurs in the case of error.
        try {
            mPhoneAccountRegistrar = new PhoneAccountRegistrar(mContext, mLock, defaultDialerCache,
                    packageName -> AppLabelProxy.Util.getAppLabel(
                            mContext.getPackageManager(), packageName));

            mContactsAsyncHelper = contactsAsyncHelperFactory.create(
                    new ContactsAsyncHelper.ContentResolverAdapter() {
                        @Override
                        public InputStream openInputStream(Context context, Uri uri)
                                throws FileNotFoundException {
                            return context.getContentResolver().openInputStream(uri);
                        }
                    });
            BluetoothDeviceManager bluetoothDeviceManager = new BluetoothDeviceManager(mContext,
                    mContext.getSystemService(BluetoothManager.class).getAdapter());
            BluetoothRouteManager bluetoothRouteManager = new BluetoothRouteManager(mContext, mLock,
                    bluetoothDeviceManager, new Timeouts.Adapter());
            BluetoothStateReceiver bluetoothStateReceiver = new BluetoothStateReceiver(
                    bluetoothDeviceManager, bluetoothRouteManager);
            mContext.registerReceiver(bluetoothStateReceiver, BluetoothStateReceiver.INTENT_FILTER);

            WiredHeadsetManager wiredHeadsetManager = new WiredHeadsetManager(mContext);
            SystemStateHelper systemStateHelper = new SystemStateHelper(mContext, mLock);

            mMissedCallNotifier = missedCallNotifierImplFactory
                    .makeMissedCallNotifierImpl(mContext, mPhoneAccountRegistrar,
                            defaultDialerCache,
                            deviceIdleControllerAdapter);
            DisconnectedCallNotifier.Factory disconnectedCallNotifierFactory =
                    new DisconnectedCallNotifier.Default();

            CallerInfoLookupHelper callerInfoLookupHelper =
                    new CallerInfoLookupHelper(context, callerInfoAsyncQueryFactory,
                            mContactsAsyncHelper, mLock);

            EmergencyCallHelper emergencyCallHelper = new EmergencyCallHelper(mContext,
                    defaultDialerCache, timeoutsAdapter);

            InCallControllerFactory inCallControllerFactory = new InCallControllerFactory() {
                @Override
                public InCallController create(Context context, SyncRoot lock,
                        CallsManager callsManager, SystemStateHelper systemStateProvider,
                        DefaultDialerCache defaultDialerCache, Timeouts.Adapter timeoutsAdapter,
                        EmergencyCallHelper emergencyCallHelper) {
                    return new InCallController(context, lock, callsManager, systemStateProvider,
                            defaultDialerCache, timeoutsAdapter, emergencyCallHelper,
                            new CarModeTracker(), clockProxy);
                }
            };

            CallDiagnosticServiceController callDiagnosticServiceController =
                    new CallDiagnosticServiceController(
                            new CallDiagnosticServiceController.ContextProxy() {
                                @Override
                                public List<ResolveInfo> queryIntentServicesAsUser(
                                        @NonNull Intent intent, int flags, int userId) {
                                    return mContext.getPackageManager().queryIntentServicesAsUser(
                                            intent, flags, userId);
                                }

                                @Override
                                public boolean bindServiceAsUser(@NonNull Intent service,
                                        @NonNull ServiceConnection conn, int flags,
                                        @NonNull UserHandle user) {
                                    return mContext.bindServiceAsUser(service, conn, flags, user);
                                }

                                @Override
                                public void unbindService(@NonNull ServiceConnection conn) {
                                    mContext.unbindService(conn);
                                }

                                @Override
                                public UserHandle getCurrentUserHandle() {
                                    return mCallsManager.getCurrentUserHandle();
                                }
                            },
                            mContext.getResources().getString(
                                    com.android.server.telecom.R.string
                                            .call_diagnostic_service_package_name),
                            mLock
                    );

            AudioProcessingNotification audioProcessingNotification =
                    new AudioProcessingNotification(mContext);

            ToastFactory toastFactory = new ToastFactory() {
                @Override
                public Toast makeText(Context context, int resId, int duration) {
                    return Toast.makeText(context, context.getMainLooper(),
                            context.getString(resId),
                            duration);
                }

                @Override
                public Toast makeText(Context context, CharSequence text, int duration) {
                    return Toast.makeText(context, context.getMainLooper(), text, duration);
                }
            };

            mCallsManager = new CallsManager(
                    mContext,
                    mLock,
                    callerInfoLookupHelper,
                    mMissedCallNotifier,
                    disconnectedCallNotifierFactory,
                    mPhoneAccountRegistrar,
                    headsetMediaButtonFactory,
                    proximitySensorManagerFactory,
                    inCallWakeLockControllerFactory,
                    connectionServiceFocusManagerFactory,
                    audioServiceFactory,
                    bluetoothRouteManager,
                    wiredHeadsetManager,
                    systemStateHelper,
                    defaultDialerCache,
                    timeoutsAdapter,
                    asyncRingtonePlayer,
                    phoneNumberUtilsAdapter,
                    emergencyCallHelper,
                    toneGeneratorFactory,
                    clockProxy,
                    audioProcessingNotification,
                    bluetoothStateReceiver,
                    callAudioRouteStateMachineFactory,
                    callAudioModeStateMachineFactory,
                    inCallControllerFactory,
                    callDiagnosticServiceController,
                    roleManagerAdapter,
                    toastFactory);

            mIncomingCallNotifier = incomingCallNotifier;
            incomingCallNotifier.setCallsManagerProxy(new IncomingCallNotifier.CallsManagerProxy() {
                @Override
                public boolean hasUnholdableCallsForOtherConnectionService(
                        PhoneAccountHandle phoneAccountHandle) {
                    return mCallsManager.hasUnholdableCallsForOtherConnectionService(
                            phoneAccountHandle);
                }

                @Override
                public int getNumUnholdableCallsForOtherConnectionService(
                        PhoneAccountHandle phoneAccountHandle) {
                    return mCallsManager.getNumUnholdableCallsForOtherConnectionService(
                            phoneAccountHandle);
                }

                @Override
                public Call getActiveCall() {
                    return mCallsManager.getActiveCall();
                }
            });
            mCallsManager.setIncomingCallNotifier(mIncomingCallNotifier);

            mRespondViaSmsManager = new RespondViaSmsManager(mCallsManager, mLock);
            mCallsManager.setRespondViaSmsManager(mRespondViaSmsManager);

            mContext.registerReceiverAsUser(mUserSwitchedReceiver, UserHandle.ALL,
                    USER_SWITCHED_FILTER, null, null);
            mContext.registerReceiverAsUser(mUserStartingReceiver, UserHandle.ALL,
                    USER_STARTING_FILTER, null, null);
            mContext.registerReceiverAsUser(mBootCompletedReceiver, UserHandle.ALL,
                    BOOT_COMPLETE_FILTER, null, null);

            // Set current user explicitly since USER_SWITCHED_FILTER intent can be missed at
            // startup
            synchronized (mLock) {
                UserHandle currentUserHandle = UserHandle.of(ActivityManager.getCurrentUser());
                mPhoneAccountRegistrar.setCurrentUserHandle(currentUserHandle);
                mCallsManager.onUserSwitch(currentUserHandle);
            }

            mCallIntentProcessor = new CallIntentProcessor(mContext, mCallsManager,
                    defaultDialerCache);
            mTelecomBroadcastIntentProcessor = new TelecomBroadcastIntentProcessor(
                    mContext, mCallsManager);

            // Register the receiver for the dialer secret codes, used to enable extended logging.
            mDialerCodeReceiver = new DialerCodeReceiver(mCallsManager);
            mContext.registerReceiver(mDialerCodeReceiver, DIALER_SECRET_CODE_FILTER,
                    Manifest.permission.CONTROL_INCALL_EXPERIENCE, null);

            // There is no USER_SWITCHED broadcast for user 0, handle it here explicitly.
            final UserManager userManager = UserManager.get(mContext);
            mTelecomServiceImpl = new TelecomServiceImpl(
                    mContext, mCallsManager, mPhoneAccountRegistrar,
                    new CallIntentProcessor.AdapterImpl(defaultDialerCache),
                    new UserCallIntentProcessorFactory() {
                        @Override
                        public UserCallIntentProcessor create(Context context,
                                UserHandle userHandle) {
                            return new UserCallIntentProcessor(context, userHandle);
                        }
                    },
                    defaultDialerCache,
                    new TelecomServiceImpl.SubscriptionManagerAdapterImpl(),
                    new TelecomServiceImpl.SettingsSecureAdapterImpl(),
                    mLock);
        } finally {
            Log.endSession();
        }
    }

    @VisibleForTesting
    public PhoneAccountRegistrar getPhoneAccountRegistrar() {
        return mPhoneAccountRegistrar;
    }

    @VisibleForTesting
    public CallsManager getCallsManager() {
        return mCallsManager;
    }

    public CallIntentProcessor getCallIntentProcessor() {
        return mCallIntentProcessor;
    }

    public TelecomBroadcastIntentProcessor getTelecomBroadcastIntentProcessor() {
        return mTelecomBroadcastIntentProcessor;
    }

    public TelecomServiceImpl getTelecomServiceImpl() {
        return mTelecomServiceImpl;
    }

    public Object getLock() {
        return mLock;
    }

    public boolean isBootComplete() {
        return mIsBootComplete;
    }
}
