/*
 * Copyright (C) 2013 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.phone;

import com.android.internal.telephony.CallerInfo;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyCapabilities;
import com.android.phone.common.CallLogAsync;

import android.net.Uri;
import android.os.SystemProperties;
import android.provider.CallLog.Calls;
import android.telephony.DisconnectCause;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
import android.util.Log;

/**
 * Helper class for interacting with the call log.
 */
class CallLogger {
    private static final String LOG_TAG = CallLogger.class.getSimpleName();
    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 1) &&
        (SystemProperties.getInt("ro.debuggable", 0) == 1);
    private static final boolean VDBG = (PhoneGlobals.DBG_LEVEL >= 2);

    private PhoneGlobals mApplication;
    private CallLogAsync mCallLog;

    public CallLogger(PhoneGlobals application, CallLogAsync callLogAsync) {
        mApplication = application;
        mCallLog = callLogAsync;
    }

    /**
     * Logs a call to the call log based on the connection object passed in.
     *
     * @param c The connection object for the call being logged.
     * @param callLogType The type of call log entry.
     */
    public void logCall(Connection c, int callLogType) {
        final String number = c.getAddress();
        final long date = c.getCreateTime();
        final long duration = c.getDurationMillis();
        final Phone phone = c.getCall().getPhone();

        final CallerInfo ci = getCallerInfoFromConnection(c);  // May be null.
        final String logNumber = getLogNumber(c, ci);

        if (DBG) {
            log("- onDisconnect(): logNumber set to:" + PhoneUtils.toLogSafePhoneNumber(logNumber) +
                ", number set to: " + PhoneUtils.toLogSafePhoneNumber(number));
        }

        // TODO: In getLogNumber we use the presentation from
        // the connection for the CNAP. Should we use the one
        // below instead? (comes from caller info)

        // For international calls, 011 needs to be logged as +
        final int presentation = getPresentation(c, ci);

        final boolean isOtaspNumber = TelephonyCapabilities.supportsOtasp(phone)
                && phone.isOtaSpNumber(number);

        // Don't log OTASP calls.
        if (!isOtaspNumber) {
            logCall(ci, logNumber, presentation, callLogType, date, duration);
        }
    }

    /**
     * Came as logCall(Connection,int) but calculates the call type from the connection object.
     */
    public void logCall(Connection c) {
        final int cause = c.getDisconnectCause();

        // Set the "type" to be displayed in the call log (see constants in CallLog.Calls)
        final int callLogType;

        if (c.isIncoming()) {
            callLogType = (cause == DisconnectCause.INCOMING_MISSED ?
                           Calls.MISSED_TYPE : Calls.INCOMING_TYPE);
        } else {
            callLogType = Calls.OUTGOING_TYPE;
        }
        if (VDBG) log("- callLogType: " + callLogType + ", UserData: " + c.getUserData());

        logCall(c, callLogType);
    }

    /**
     * Logs a call to the call from the parameters passed in.
     */
    public void logCall(CallerInfo ci, String number, int presentation, int callType, long start,
                        long duration) {
        // no-op
    }

    /**
     * Get the caller info.
     *
     * @param conn The phone connection.
     * @return The CallerInfo associated with the connection. Maybe null.
     */
    private CallerInfo getCallerInfoFromConnection(Connection conn) {
        CallerInfo ci = null;
        Object o = conn.getUserData();

        if ((o == null) || (o instanceof CallerInfo)) {
            ci = (CallerInfo) o;
        } else if (o instanceof Uri) {
            ci = CallerInfo.getCallerInfo(mApplication.getApplicationContext(), (Uri) o);
        } else {
            ci = ((PhoneUtils.CallerInfoToken) o).currentInfo;
        }
        return ci;
    }

    /**
     * Retrieve the phone number from the caller info or the connection.
     *
     * For incoming call the number is in the Connection object. For
     * outgoing call we use the CallerInfo phoneNumber field if
     * present. All the processing should have been done already (CDMA vs GSM numbers).
     *
     * If CallerInfo is missing the phone number, get it from the connection.
     * Apply the Call Name Presentation (CNAP) transform in the connection on the number.
     *
     * @param conn The phone connection.
     * @param callerInfo The CallerInfo. Maybe null.
     * @return the phone number.
     */
    private String getLogNumber(Connection conn, CallerInfo callerInfo) {
        String number = null;

        if (conn.isIncoming()) {
            number = conn.getAddress();
        } else {
            // For emergency and voicemail calls,
            // CallerInfo.phoneNumber does *not* contain a valid phone
            // number.  Instead it contains an I18N'd string such as
            // "Emergency Number" or "Voice Mail" so we get the number
            // from the connection.
            if (null == callerInfo || TextUtils.isEmpty(callerInfo.phoneNumber) ||
                callerInfo.isEmergencyNumber() || callerInfo.isVoiceMailNumber()) {
                if (conn.getCall().getPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
                    // In cdma getAddress() is not always equals to getOrigDialString().
                    number = conn.getOrigDialString();
                } else {
                    number = conn.getAddress();
                }
            } else {
                number = callerInfo.phoneNumber;
            }
        }

        if (null == number) {
            return null;
        } else {
            int presentation = conn.getNumberPresentation();

            // Do final CNAP modifications.
            String newNumber = PhoneUtils.modifyForSpecialCnapCases(mApplication, callerInfo,
                                                          number, presentation);

            if (!PhoneNumberUtils.isUriNumber(number)) {
                number = PhoneNumberUtils.stripSeparators(number);
            }
            if (VDBG) log("getLogNumber: " + number);
            return number;
        }
    }

    /**
     * Get the presentation from the callerinfo if not null otherwise,
     * get it from the connection.
     *
     * @param conn The phone connection.
     * @param callerInfo The CallerInfo. Maybe null.
     * @return The presentation to use in the logs.
     */
    private int getPresentation(Connection conn, CallerInfo callerInfo) {
        int presentation;

        if (null == callerInfo) {
            presentation = conn.getNumberPresentation();
        } else {
            presentation = callerInfo.numberPresentation;
            if (DBG) log("- getPresentation(): ignoring connection's presentation: " +
                         conn.getNumberPresentation());
        }
        if (DBG) log("- getPresentation: presentation: " + presentation);
        return presentation;
    }

    private void log(String msg) {
        Log.d(LOG_TAG, msg);
    }
}
