/*
 * 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.tv.search;

import android.app.SearchManager;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.Log;

import com.android.tv.common.CommonConstants;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.dagger.init.SafePreDaggerInitializer;
import com.android.tv.common.util.CommonUtils;
import com.android.tv.common.util.PermissionUtils;
import com.android.tv.perf.EventNames;
import com.android.tv.perf.PerformanceMonitor;
import com.android.tv.perf.TimerEvent;
import com.android.tv.util.TvUriMatcher;

import com.google.auto.value.AutoValue;

import dagger.android.ContributesAndroidInjector;
import dagger.android.DaggerContentProvider;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.inject.Inject;

/** Content provider for local search */
public class LocalSearchProvider extends DaggerContentProvider {
    private static final String TAG = "LocalSearchProvider";
    private static final boolean DEBUG = false;

    /** The authority for LocalSearchProvider. */
    public static final String AUTHORITY = CommonConstants.BASE_PACKAGE + ".search";

    // TODO: Remove this once added to the SearchManager.
    private static final String SUGGEST_COLUMN_PROGRESS_BAR_PERCENTAGE = "progress_bar_percentage";

    private static final String[] SEARCHABLE_COLUMNS =
            new String[] {
                SearchManager.SUGGEST_COLUMN_TEXT_1,
                SearchManager.SUGGEST_COLUMN_TEXT_2,
                SearchManager.SUGGEST_COLUMN_RESULT_CARD_IMAGE,
                SearchManager.SUGGEST_COLUMN_INTENT_ACTION,
                SearchManager.SUGGEST_COLUMN_INTENT_DATA,
                SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA,
                SearchManager.SUGGEST_COLUMN_CONTENT_TYPE,
                SearchManager.SUGGEST_COLUMN_IS_LIVE,
                SearchManager.SUGGEST_COLUMN_VIDEO_WIDTH,
                SearchManager.SUGGEST_COLUMN_VIDEO_HEIGHT,
                SearchManager.SUGGEST_COLUMN_DURATION,
                SUGGEST_COLUMN_PROGRESS_BAR_PERCENTAGE
            };

    private static final String EXPECTED_PATH_PREFIX = "/" + SearchManager.SUGGEST_URI_PATH_QUERY;
    static final String SUGGEST_PARAMETER_ACTION = "action";
    // The launcher passes 10 as a 'limit' parameter by default.
    @VisibleForTesting static final int DEFAULT_SEARCH_LIMIT = 10;

    @VisibleForTesting
    static final int DEFAULT_SEARCH_ACTION = SearchInterface.ACTION_TYPE_AMBIGUOUS;

    private static final String NO_LIVE_CONTENTS = "0";
    private static final String LIVE_CONTENTS = "1";

    @Inject PerformanceMonitor mPerformanceMonitor;

    /** Used only for testing */
    private SearchInterface mSearchInterface;

    @Override
    public boolean onCreate() {
        SafePreDaggerInitializer.init(getContext());
        if (!super.onCreate()) {
            Log.e(TAG, "LocalSearchProvider.onCreate() failed.");
            return false;
        }
        return true;
    }

    @VisibleForTesting
    void setSearchInterface(SearchInterface searchInterface) {
        SoftPreconditions.checkState(CommonUtils.isRunningInTest());
        mSearchInterface = searchInterface;
    }

    @Override
    public Cursor query(
            @NonNull Uri uri,
            String[] projection,
            String selection,
            String[] selectionArgs,
            String sortOrder) {
        if (TvUriMatcher.match(uri) != TvUriMatcher.MATCH_ON_DEVICE_SEARCH) {
            throw new IllegalArgumentException("Unknown URI: " + uri);
        }
        TimerEvent queryTimer = mPerformanceMonitor.startTimer();
        if (DEBUG) {
            Log.d(
                    TAG,
                    "query("
                            + uri
                            + ", "
                            + Arrays.toString(projection)
                            + ", "
                            + selection
                            + ", "
                            + Arrays.toString(selectionArgs)
                            + ", "
                            + sortOrder
                            + ")");
        }
        long time = SystemClock.elapsedRealtime();
        SearchInterface search = mSearchInterface;
        if (search == null) {
            if (PermissionUtils.hasAccessAllEpg(getContext())) {
                if (DEBUG) Log.d(TAG, "Performing TV Provider search.");
                search = new TvProviderSearch(getContext());
            } else {
                if (DEBUG) Log.d(TAG, "Performing Data Manager search.");
                search = new DataManagerSearch(getContext());
            }
        }
        String query = uri.getLastPathSegment();
        int limit =
                getQueryParamater(uri, SearchManager.SUGGEST_PARAMETER_LIMIT, DEFAULT_SEARCH_LIMIT);
        if (limit <= 0) {
            limit = DEFAULT_SEARCH_LIMIT;
        }
        int action = getQueryParamater(uri, SUGGEST_PARAMETER_ACTION, DEFAULT_SEARCH_ACTION);
        if (action < SearchInterface.ACTION_TYPE_START
                || action > SearchInterface.ACTION_TYPE_END) {
            action = DEFAULT_SEARCH_ACTION;
        }
        List<SearchResult> results = new ArrayList<>();
        if (!TextUtils.isEmpty(query)) {
            results.addAll(search.search(query, limit, action));
        }
        Cursor c = createSuggestionsCursor(results);
        if (DEBUG) {
            Log.d(
                    TAG,
                    "Elapsed time(count="
                            + c.getCount()
                            + "): "
                            + (SystemClock.elapsedRealtime() - time)
                            + "(msec)");
        }
        mPerformanceMonitor.stopTimer(queryTimer, EventNames.ON_DEVICE_SEARCH);
        return c;
    }

    private int getQueryParamater(Uri uri, String key, int defaultValue) {
        try {
            return Integer.parseInt(uri.getQueryParameter(key));
        } catch (NumberFormatException | UnsupportedOperationException e) {
            // Ignore the exceptions
        }
        return defaultValue;
    }

    private Cursor createSuggestionsCursor(List<SearchResult> results) {
        MatrixCursor cursor = new MatrixCursor(SEARCHABLE_COLUMNS, results.size());
        List<String> row = new ArrayList<>(SEARCHABLE_COLUMNS.length);

        int index = 0;
        for (SearchResult result : results) {
            row.clear();
            row.add(result.getTitle());
            row.add(result.getDescription());
            row.add(result.getImageUri());
            row.add(result.getIntentAction());
            row.add(result.getIntentData());
            row.add(result.getIntentExtraData());
            row.add(result.getContentType());
            row.add(result.getIsLive() ? LIVE_CONTENTS : NO_LIVE_CONTENTS);
            row.add(result.getVideoWidth() == 0 ? null : String.valueOf(result.getVideoWidth()));
            row.add(result.getVideoHeight() == 0 ? null : String.valueOf(result.getVideoHeight()));
            row.add(result.getDuration() == 0 ? null : String.valueOf(result.getDuration()));
            row.add(String.valueOf(result.getProgressPercentage()));
            cursor.addRow(row);
            if (DEBUG) Log.d(TAG, "Result[" + (++index) + "]: " + result);
        }
        return cursor;
    }

    @Override
    public String getType(Uri uri) {
        if (!checkUriCorrect(uri)) return null;
        return SearchManager.SUGGEST_MIME_TYPE;
    }

    private static boolean checkUriCorrect(Uri uri) {
        return uri != null && uri.getPath().startsWith(EXPECTED_PATH_PREFIX);
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        throw new UnsupportedOperationException();
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        throw new UnsupportedOperationException();
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        throw new UnsupportedOperationException();
    }

    /** Module for {@link LocalSearchProvider} */
    @dagger.Module
    public abstract static class Module {
        @ContributesAndroidInjector
        abstract LocalSearchProvider contributesLocalSearchProviderInjector();
    }

    /** A placeholder to a search result. */
    @AutoValue
    public abstract static class SearchResult {
        public static Builder builder() {
            // primitive fields cannot be nullable. Set to default;
            return new AutoValue_LocalSearchProvider_SearchResult.Builder()
                    .setChannelId(0)
                    .setIsLive(false)
                    .setVideoWidth(0)
                    .setVideoHeight(0)
                    .setDuration(0)
                    .setProgressPercentage(0);
        }

        public abstract Builder toBuilder();

        @AutoValue.Builder
        abstract static class Builder {
            abstract Builder setChannelId(long value);

            abstract Builder setChannelNumber(String value);

            abstract Builder setTitle(String value);

            abstract Builder setDescription(String value);

            abstract Builder setImageUri(String value);

            abstract Builder setIntentAction(String value);

            abstract Builder setIntentData(String value);

            abstract Builder setIntentExtraData(String value);

            abstract Builder setContentType(String value);

            abstract Builder setIsLive(boolean value);

            abstract Builder setVideoWidth(int value);

            abstract Builder setVideoHeight(int value);

            abstract Builder setDuration(long value);

            abstract Builder setProgressPercentage(int value);

            abstract SearchResult build();
        }

        abstract long getChannelId();

        @Nullable
        abstract String getChannelNumber();

        @Nullable
        abstract String getTitle();

        @Nullable
        abstract String getDescription();

        @Nullable
        abstract String getImageUri();

        @Nullable
        abstract String getIntentAction();

        @Nullable
        abstract String getIntentData();

        @Nullable
        abstract String getIntentExtraData();

        @Nullable
        abstract String getContentType();

        abstract boolean getIsLive();

        abstract int getVideoWidth();

        abstract int getVideoHeight();

        abstract long getDuration();

        abstract int getProgressPercentage();
    }
}
