/*
 * Copyright (C) 2016 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.annotation.Nullable;
import android.content.Context;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.telecom.Log;
import android.telecom.Logging.Runnable;
import android.telecom.Logging.Session;
import android.text.TextUtils;
import android.util.Pair;

import com.android.internal.annotations.VisibleForTesting;
import android.telecom.CallerInfo;
import android.telecom.CallerInfoAsyncQuery;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

public class CallerInfoLookupHelper {
    public interface OnQueryCompleteListener {
        /**
         * Called when the query returns with the caller info
         * @param info
         * @return true if the value should be cached, false otherwise.
         */
        void onCallerInfoQueryComplete(Uri handle, @Nullable CallerInfo info);
        void onContactPhotoQueryComplete(Uri handle, CallerInfo info);
    }

    private static class CallerInfoQueryInfo {
        public CallerInfo callerInfo;
        public List<OnQueryCompleteListener> listeners;
        public boolean imageQueryPending = false;

        public CallerInfoQueryInfo() {
            listeners = new LinkedList<>();
        }
    }

    private final Map<Uri, CallerInfoQueryInfo> mQueryEntries = new HashMap<>();

    private final CallerInfoAsyncQueryFactory mCallerInfoAsyncQueryFactory;
    private final ContactsAsyncHelper mContactsAsyncHelper;
    private final Context mContext;
    private final TelecomSystem.SyncRoot mLock;
    private final Handler mHandler = new Handler(Looper.getMainLooper());

    public CallerInfoLookupHelper(Context context,
            CallerInfoAsyncQueryFactory callerInfoAsyncQueryFactory,
            ContactsAsyncHelper contactsAsyncHelper,
            TelecomSystem.SyncRoot lock) {
        mCallerInfoAsyncQueryFactory = callerInfoAsyncQueryFactory;
        mContactsAsyncHelper = contactsAsyncHelper;
        mContext = context;
        mLock = lock;
    }

    /**
     * Generates a CompletableFuture which performs a contacts lookup asynchronously.  The future
     * returns a {@link Pair} containing the original handle which is being looked up and any
     * {@link CallerInfo} which was found.
     * @param handle
     * @return {@link CompletableFuture} to perform the contacts lookup.
     */
    public CompletableFuture<Pair<Uri, CallerInfo>> startLookup(final Uri handle) {
        // Create the returned future and
        final CompletableFuture<Pair<Uri, CallerInfo>> callerInfoFuture = new CompletableFuture<>();

        final String number = handle.getSchemeSpecificPart();
        if (TextUtils.isEmpty(number)) {
            // Nothing to do here, just finish.
            Log.d(CallerInfoLookupHelper.this, "onCallerInfoQueryComplete - no number; end early");
            callerInfoFuture.complete(new Pair<>(handle, null));
            return callerInfoFuture;
        }

        // Setup a query complete listener which will get the results of the contacts lookup.
        OnQueryCompleteListener listener = new OnQueryCompleteListener() {
            @Override
            public void onCallerInfoQueryComplete(Uri handle, CallerInfo info) {
                Log.d(CallerInfoLookupHelper.this, "onCallerInfoQueryComplete - found info for %s",
                        Log.piiHandle(handle));
                // Got something, so complete the future.
                callerInfoFuture.complete(new Pair<>(handle, info));
            }

            @Override
            public void onContactPhotoQueryComplete(Uri handle, CallerInfo info) {
                // No-op for now; not something this future cares about.
            }
        };

        // Start async lookup.
        startLookup(handle, listener);

        return callerInfoFuture;
    }

    public void startLookup(final Uri handle, OnQueryCompleteListener listener) {
        if (handle == null) {
            listener.onCallerInfoQueryComplete(handle, null);
            return;
        }

        final String number = handle.getSchemeSpecificPart();
        if (TextUtils.isEmpty(number)) {
            listener.onCallerInfoQueryComplete(handle, null);
            return;
        }

        synchronized (mLock) {
            if (mQueryEntries.containsKey(handle)) {
                CallerInfoQueryInfo info = mQueryEntries.get(handle);
                if (info.callerInfo != null) {
                    Log.i(this, "Caller info already exists for handle %s; using cached value",
                            Log.piiHandle(handle));
                    listener.onCallerInfoQueryComplete(handle, info.callerInfo);
                    if (!info.imageQueryPending && (info.callerInfo.cachedPhoto != null ||
                            info.callerInfo.cachedPhotoIcon != null)) {
                        listener.onContactPhotoQueryComplete(handle, info.callerInfo);
                    } else if (info.imageQueryPending) {
                        Log.i(this, "There is a pending photo query for handle %s. " +
                                "Adding to listeners for this query.", Log.piiHandle(handle));
                        info.listeners.add(listener);
                    }
                } else {
                    Log.i(this, "There is a previously incomplete query for handle %s. Adding to " +
                            "listeners for this query.", Log.piiHandle(handle));
                    info.listeners.add(listener);
                }
                // Since we have a pending query for this handle already, don't re-query it.
                return;
            } else {
                CallerInfoQueryInfo info = new CallerInfoQueryInfo();
                info.listeners.add(listener);
                mQueryEntries.put(handle, info);
            }
        }

        mHandler.post(new Runnable("CILH.sL", null) {
            @Override
            public void loggedRun() {
                Session continuedSession = Log.createSubsession();
                try {
                    CallerInfoAsyncQuery query = mCallerInfoAsyncQueryFactory.startQuery(
                            0, mContext, number,
                            makeCallerInfoQueryListener(handle), continuedSession);
                    if (query == null) {
                        Log.w(this, "Lookup failed for %s.", Log.piiHandle(handle));
                        Log.cancelSubsession(continuedSession);
                    }
                } catch (Throwable t) {
                    Log.cancelSubsession(continuedSession);
                    throw t;
                }
            }
        }.prepare());
    }

    private CallerInfoAsyncQuery.OnQueryCompleteListener makeCallerInfoQueryListener(
            final Uri handle) {
        return (token, cookie, ci) -> {
            synchronized (mLock) {
                Log.continueSession((Session) cookie, "CILH.oQC");
                try {
                    if (mQueryEntries.containsKey(handle)) {
                        Log.i(CallerInfoLookupHelper.this, "CI query for handle %s has completed;" +
                                " notifying all listeners.", Log.piiHandle(handle));
                        CallerInfoQueryInfo info = mQueryEntries.get(handle);
                        for (OnQueryCompleteListener l : info.listeners) {
                            l.onCallerInfoQueryComplete(handle, ci);
                        }
                        if (ci.getContactDisplayPhotoUri() == null) {
                            Log.i(CallerInfoLookupHelper.this, "There is no photo for this " +
                                    "contact, skipping photo query");
                            mQueryEntries.remove(handle);
                        } else {
                            info.callerInfo = ci;
                            info.imageQueryPending = true;
                            startPhotoLookup(handle, ci.getContactDisplayPhotoUri());
                        }
                    } else {
                        Log.i(CallerInfoLookupHelper.this, "CI query for handle %s has completed," +
                                " but there are no listeners left.", Log.piiHandle(handle));
                    }
                } finally {
                    Log.endSession();
                }
            }
        };
    }

    private void startPhotoLookup(final Uri handle, final Uri contactPhotoUri) {
        mHandler.post(new Runnable("CILH.sPL", null) {
            @Override
            public void loggedRun() {
                Session continuedSession = Log.createSubsession();
                try {
                    mContactsAsyncHelper.startObtainPhotoAsync(
                            0, mContext, contactPhotoUri,
                            makeContactPhotoListener(handle), continuedSession);
                } catch (Throwable t) {
                    Log.cancelSubsession(continuedSession);
                    throw t;
                }
            }
        }.prepare());
    }

    private ContactsAsyncHelper.OnImageLoadCompleteListener makeContactPhotoListener(
            final Uri handle) {
        return (token, photo, photoIcon, cookie) -> {
            synchronized (mLock) {
                Log.continueSession((Session) cookie, "CLIH.oILC");
                try {
                    if (mQueryEntries.containsKey(handle)) {
                        CallerInfoQueryInfo info = mQueryEntries.get(handle);
                        if (info.callerInfo == null) {
                            Log.w(CallerInfoLookupHelper.this, "Photo query finished, but the " +
                                    "CallerInfo object previously looked up was not cached.");
                            mQueryEntries.remove(handle);
                            return;
                        }
                        info.callerInfo.cachedPhoto = photo;
                        info.callerInfo.cachedPhotoIcon = photoIcon;
                        for (OnQueryCompleteListener l : info.listeners) {
                            l.onContactPhotoQueryComplete(handle, info.callerInfo);
                        }
                        mQueryEntries.remove(handle);
                    } else {
                        Log.i(CallerInfoLookupHelper.this, "Photo query for handle %s has" +
                                " completed, but there are no listeners left.",
                                Log.piiHandle(handle));
                    }
                } finally {
                    Log.endSession();
                }
            }
        };
    }

    @VisibleForTesting
    public Map<Uri, CallerInfoQueryInfo> getCallerInfoEntries() {
        return mQueryEntries;
    }

    @VisibleForTesting
    public Handler getHandler() {
        return mHandler;
    }
}
