/*
 * Copyright 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.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.telecom.CallState;
import android.telecom.PhoneAccountHandle;
import android.telephony.TelephonyManager;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;

import java.util.Collection;
import java.util.Objects;

/**
 * Registers a timeout for a call and disconnects the call when the timeout expires.
 */
final class CreateConnectionTimeout extends PhoneStateListener implements Runnable {
    private final Context mContext;
    private final PhoneAccountRegistrar mPhoneAccountRegistrar;
    private final ConnectionServiceWrapper mConnectionService;
    private final Call mCall;
    private final Handler mHandler = new Handler();
    private boolean mIsRegistered;
    private boolean mIsCallTimedOut;

    CreateConnectionTimeout(Context context, PhoneAccountRegistrar phoneAccountRegistrar,
            ConnectionServiceWrapper service, Call call) {
        mContext = context;
        mPhoneAccountRegistrar = phoneAccountRegistrar;
        mConnectionService = service;
        mCall = call;
    }

    boolean isTimeoutNeededForCall(Collection<PhoneAccountHandle> accounts,
            PhoneAccountHandle currentAccount) {
        // Non-emergency calls timeout automatically at the radio layer. No need for a timeout here.
        if (!TelephonyUtil.shouldProcessAsEmergency(mContext, mCall.getHandle())) {
            return false;
        }

        // If there's no connection manager to fallback on then there's no point in having a
        // timeout.
        PhoneAccountHandle connectionManager = mPhoneAccountRegistrar.getSimCallManager();
        if (!accounts.contains(connectionManager)) {
            return false;
        }

        // No need to add a timeout if the current attempt is over the connection manager.
        if (Objects.equals(connectionManager, currentAccount)) {
            return false;
        }

        // To reduce the number of scenarios where a timeout is needed, only use a timeout if
        // we're connected to Wi-Fi. This ensures that the fallback connection manager has an
        // alternate route to place the call. TODO: remove this condition or allow connection
        // managers to specify transports. See http://b/19199181.
        if (!isConnectedToWifi()) {
            return false;
        }

        Log.d(this, "isTimeoutNeededForCall, returning true");
        return true;
    }

    void registerTimeout() {
        Log.d(this, "registerTimeout");
        mIsRegistered = true;
        // First find out the cellular service state. Based on the state we decide whether a timeout
        // will actually be enforced and if so how long it should be.
        TelephonyManager telephonyManager =
            (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
        telephonyManager.listen(this, PhoneStateListener.LISTEN_SERVICE_STATE);
        telephonyManager.listen(this, 0);
    }

    void unregisterTimeout() {
        Log.d(this, "unregisterTimeout");
        mIsRegistered = false;
        mHandler.removeCallbacksAndMessages(null);
    }

    boolean isCallTimedOut() {
        return mIsCallTimedOut;
    }

    @Override
    public void onServiceStateChanged(ServiceState serviceState) {
        long timeoutLengthMillis = getTimeoutLengthMillis(serviceState);
        if (!mIsRegistered) {
            Log.d(this, "onServiceStateChanged, timeout no longer registered, skipping");
        } else if (timeoutLengthMillis  <= 0) {
            Log.d(this, "onServiceStateChanged, timeout set to %d, skipping", timeoutLengthMillis);
        } else if (serviceState.getState() == ServiceState.STATE_IN_SERVICE) {
            // If cellular service is available then don't bother with a timeout.
            Log.d(this, "onServiceStateChanged, cellular service available, skipping");
        } else {
            mHandler.postDelayed(this, timeoutLengthMillis);
        }
    }

    @Override
    public void run() {
        if (mIsRegistered && isCallBeingPlaced(mCall)) {
            Log.d(this, "run, call timed out, calling disconnect");
            mIsCallTimedOut = true;
            mConnectionService.disconnect(mCall);
        }
    }

    static boolean isCallBeingPlaced(Call call) {
        int state = call.getState();
        return state == CallState.NEW
            || state == CallState.CONNECTING
            || state == CallState.DIALING;
    }

    private long getTimeoutLengthMillis(ServiceState serviceState) {
        // If the radio is off then use a longer timeout. This gives us more time to power on the
        // radio.
        if (serviceState.getState() == ServiceState.STATE_POWER_OFF) {
            return Timeouts.getEmergencyCallTimeoutRadioOffMillis(
                    mContext.getContentResolver());
        } else {
            return Timeouts.getEmergencyCallTimeoutMillis(mContext.getContentResolver());
        }
    }

    private boolean isConnectedToWifi() {
        ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(
            Context.CONNECTIVITY_SERVICE);
        if (cm != null) {
          NetworkInfo ni = cm.getActiveNetworkInfo();
          return ni != null && ni.isConnected() && ni.getType() == ConnectivityManager.TYPE_WIFI;
        }
        return false;
    }
}
