/*
 * 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.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.media.tv.TvContentRating;
import android.media.tv.TvContract;
import android.media.tv.TvContract.Channels;
import android.media.tv.TvContract.Programs;
import android.media.tv.TvContract.WatchedPrograms;
import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager;
import android.net.Uri;
import android.os.SystemClock;
import android.support.annotation.WorkerThread;
import android.text.TextUtils;
import android.util.Log;
import com.android.tv.common.TvContentRatingCache;
import com.android.tv.common.util.PermissionUtils;
import com.android.tv.search.LocalSearchProvider.SearchResult;
import com.android.tv.util.Utils;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/** An implementation of {@link SearchInterface} to search query from TvProvider directly. */
public class TvProviderSearch implements SearchInterface {
    private static final String TAG = "TvProviderSearch";
    private static final boolean DEBUG = false;

    private static final long SEARCH_TIME_FRAME_MS = TimeUnit.DAYS.toMillis(14);

    private static final int NO_LIMIT = 0;

    private final Context mContext;
    private final ContentResolver mContentResolver;
    private final TvInputManager mTvInputManager;
    private final TvContentRatingCache mTvContentRatingCache = TvContentRatingCache.getInstance();

    TvProviderSearch(Context context) {
        mContext = context;
        mContentResolver = context.getContentResolver();
        mTvInputManager = (TvInputManager) context.getSystemService(Context.TV_INPUT_SERVICE);
    }

    /**
     * Search channels, inputs, or programs from TvProvider. This assumes that parental control
     * settings will not be change while searching.
     *
     * @param action One of {@link #ACTION_TYPE_SWITCH_CHANNEL}, {@link #ACTION_TYPE_SWITCH_INPUT},
     *     or {@link #ACTION_TYPE_AMBIGUOUS},
     */
    @Override
    @WorkerThread
    public List<SearchResult> search(String query, int limit, int action) {
        // TODO(b/72499463): add a test.
        List<SearchResult> results = new ArrayList<>();
        if (!PermissionUtils.hasAccessAllEpg(mContext)) {
            // TODO: support this feature for non-system LC app. b/23939816
            return results;
        }
        Set<Long> channelsFound = new HashSet<>();
        if (action == ACTION_TYPE_SWITCH_CHANNEL) {
            results.addAll(searchChannels(query, channelsFound, limit));
        } else if (action == ACTION_TYPE_SWITCH_INPUT) {
            results.addAll(searchInputs(query, limit));
        } else {
            // Search channels first.
            results.addAll(searchChannels(query, channelsFound, limit));
            if (results.size() >= limit) {
                return results;
            }

            // In case the user wanted to perform the action "switch to XXX", which is indicated by
            // setting the limit to 1, search inputs.
            if (limit == 1) {
                results.addAll(searchInputs(query, limit));
                if (!results.isEmpty()) {
                    return results;
                }
            }

            // Lastly, search programs.
            limit -= results.size();
            results.addAll(
                    searchPrograms(
                            query,
                            null,
                            new String[] {Programs.COLUMN_TITLE, Programs.COLUMN_SHORT_DESCRIPTION},
                            channelsFound,
                            limit));
        }
        return results;
    }

    private void appendSelectionString(
            StringBuilder sb, String[] columnForExactMatching, String[] columnForPartialMatching) {
        boolean firstColumn = true;
        if (columnForExactMatching != null) {
            for (String column : columnForExactMatching) {
                if (!firstColumn) {
                    sb.append(" OR ");
                } else {
                    firstColumn = false;
                }
                sb.append(column).append("=?");
            }
        }
        if (columnForPartialMatching != null) {
            for (String column : columnForPartialMatching) {
                if (!firstColumn) {
                    sb.append(" OR ");
                } else {
                    firstColumn = false;
                }
                sb.append(column).append(" LIKE ?");
            }
        }
    }

    private void insertSelectionArgumentStrings(
            String[] selectionArgs,
            int pos,
            String query,
            String[] columnForExactMatching,
            String[] columnForPartialMatching) {
        if (columnForExactMatching != null) {
            int until = pos + columnForExactMatching.length;
            for (; pos < until; ++pos) {
                selectionArgs[pos] = query;
            }
        }
        String selectionArg = "%" + query + "%";
        if (columnForPartialMatching != null) {
            int until = pos + columnForPartialMatching.length;
            for (; pos < until; ++pos) {
                selectionArgs[pos] = selectionArg;
            }
        }
    }

    @WorkerThread
    private List<SearchResult> searchChannels(String query, Set<Long> channels, int limit) {
        if (DEBUG) Log.d(TAG, "Searching channels: '" + query + "'");
        long time = SystemClock.elapsedRealtime();
        List<SearchResult> results = new ArrayList<>();
        if (TextUtils.isDigitsOnly(query)) {
            results.addAll(
                    searchChannels(
                            query,
                            new String[] {Channels.COLUMN_DISPLAY_NUMBER},
                            null,
                            channels,
                            NO_LIMIT));
            if (results.size() > 1) {
                Collections.sort(results, new ChannelComparatorWithSameDisplayNumber());
            }
        }
        if (results.size() < limit) {
            results.addAll(
                    searchChannels(
                            query,
                            null,
                            new String[] {
                                Channels.COLUMN_DISPLAY_NAME, Channels.COLUMN_DESCRIPTION
                            },
                            channels,
                            limit - results.size()));
        }
        if (results.size() > limit) {
            results = results.subList(0, limit);
        }
        for (int i = 0; i < results.size(); i++) {
            results.set(i, fillProgramInfo(results.get(i)));
        }
        if (DEBUG) {
            Log.d(
                    TAG,
                    "Found "
                            + results.size()
                            + " channels. Elapsed time for searching"
                            + " channels: "
                            + (SystemClock.elapsedRealtime() - time)
                            + "(msec)");
        }
        return results;
    }

    @WorkerThread
    private List<SearchResult> searchChannels(
            String query,
            String[] columnForExactMatching,
            String[] columnForPartialMatching,
            Set<Long> channelsFound,
            int limit) {
        String[] projection = {
            Channels._ID,
            Channels.COLUMN_DISPLAY_NUMBER,
            Channels.COLUMN_DISPLAY_NAME,
            Channels.COLUMN_DESCRIPTION
        };

        StringBuilder sb = new StringBuilder();
        sb.append(Channels.COLUMN_BROWSABLE)
                .append("=1 AND ")
                .append(Channels.COLUMN_SEARCHABLE)
                .append("=1");
        if (mTvInputManager.isParentalControlsEnabled()) {
            sb.append(" AND ").append(Channels.COLUMN_LOCKED).append("=0");
        }
        sb.append(" AND (");
        appendSelectionString(sb, columnForExactMatching, columnForPartialMatching);
        sb.append(")");
        String selection = sb.toString();

        int len =
                (columnForExactMatching == null ? 0 : columnForExactMatching.length)
                        + (columnForPartialMatching == null ? 0 : columnForPartialMatching.length);
        String[] selectionArgs = new String[len];
        insertSelectionArgumentStrings(
                selectionArgs, 0, query, columnForExactMatching, columnForPartialMatching);

        List<SearchResult> searchResults = new ArrayList<>();

        try (Cursor c =
                mContentResolver.query(
                        Channels.CONTENT_URI, projection, selection, selectionArgs, null)) {
            if (c != null) {
                int count = 0;
                while (c.moveToNext()) {
                    long id = c.getLong(0);
                    // Filter out the channel which has been already searched.
                    if (channelsFound.contains(id)) {
                        continue;
                    }
                    channelsFound.add(id);

                    SearchResult.Builder result = SearchResult.builder();
                    result.setChannelId(id);
                    result.setChannelNumber(c.getString(1));
                    result.setTitle(c.getString(2));
                    result.setDescription(c.getString(3));
                    result.setImageUri(TvContract.buildChannelLogoUri(id).toString());
                    result.setIntentAction(Intent.ACTION_VIEW);
                    result.setIntentData(buildIntentData(id));
                    result.setContentType(Programs.CONTENT_ITEM_TYPE);
                    result.setIsLive(true);
                    result.setProgressPercentage(LocalSearchProvider.PROGRESS_PERCENTAGE_HIDE);

                    searchResults.add(result.build());

                    if (limit != NO_LIMIT && ++count >= limit) {
                        break;
                    }
                }
            }
        }
        return searchResults;
    }

    /**
     * Replaces the channel information - title, description, channel logo - with the current
     * program information of the channel if the current program information exists and it is not
     * blocked.
     */
    @WorkerThread
    private SearchResult fillProgramInfo(SearchResult result) {
        long now = System.currentTimeMillis();
        Uri uri = TvContract.buildProgramsUriForChannel(result.getChannelId(), now, now);
        String[] projection =
                new String[] {
                    Programs.COLUMN_TITLE,
                    Programs.COLUMN_POSTER_ART_URI,
                    Programs.COLUMN_CONTENT_RATING,
                    Programs.COLUMN_VIDEO_WIDTH,
                    Programs.COLUMN_VIDEO_HEIGHT,
                    Programs.COLUMN_START_TIME_UTC_MILLIS,
                    Programs.COLUMN_END_TIME_UTC_MILLIS
                };

        try (Cursor c = mContentResolver.query(uri, projection, null, null, null)) {
            if (c != null && c.moveToNext() && !isRatingBlocked(c.getString(2))) {
                String channelName = result.getTitle();
                String channelNumber = result.getChannelNumber();
                SearchResult.Builder builder = SearchResult.builder();
                long startUtcMillis = c.getLong(5);
                long endUtcMillis = c.getLong(6);
                builder.setTitle(c.getString(0));
                builder.setDescription(
                        buildProgramDescription(
                                channelNumber, channelName, startUtcMillis, endUtcMillis));
                String imageUri = c.getString(1);
                if (imageUri != null) {
                    builder.setImageUri(imageUri);
                }
                builder.setVideoWidth(c.getInt(3));
                builder.setVideoHeight(c.getInt(4));
                builder.setDuration(endUtcMillis - startUtcMillis);
                builder.setProgressPercentage(getProgressPercentage(startUtcMillis, endUtcMillis));
                return builder.build();
            }
        }
        return result;
    }

    private String buildProgramDescription(
            String channelNumber,
            String channelName,
            long programStartUtcMillis,
            long programEndUtcMillis) {
        return Utils.getDurationString(mContext, programStartUtcMillis, programEndUtcMillis, false)
                + System.lineSeparator()
                + channelNumber
                + " "
                + channelName;
    }

    private int getProgressPercentage(long startUtcMillis, long endUtcMillis) {
        long current = System.currentTimeMillis();
        if (startUtcMillis > current || endUtcMillis <= current) {
            return LocalSearchProvider.PROGRESS_PERCENTAGE_HIDE;
        }
        return (int) (100 * (current - startUtcMillis) / (endUtcMillis - startUtcMillis));
    }

    @WorkerThread
    private List<SearchResult> searchPrograms(
            String query,
            String[] columnForExactMatching,
            String[] columnForPartialMatching,
            Set<Long> channelsFound,
            int limit) {
        if (DEBUG) Log.d(TAG, "Searching programs: '" + query + "'");
        long time = SystemClock.elapsedRealtime();
        String[] projection = {
            Programs.COLUMN_CHANNEL_ID,
            Programs.COLUMN_TITLE,
            Programs.COLUMN_POSTER_ART_URI,
            Programs.COLUMN_CONTENT_RATING,
            Programs.COLUMN_VIDEO_WIDTH,
            Programs.COLUMN_VIDEO_HEIGHT,
            Programs.COLUMN_START_TIME_UTC_MILLIS,
            Programs.COLUMN_END_TIME_UTC_MILLIS,
            Programs._ID
        };

        StringBuilder sb = new StringBuilder();
        // Search among the programs which are now being on the air.
        sb.append(Programs.COLUMN_START_TIME_UTC_MILLIS).append("<=? AND ");
        sb.append(Programs.COLUMN_END_TIME_UTC_MILLIS).append(">=? AND (");
        appendSelectionString(sb, columnForExactMatching, columnForPartialMatching);
        sb.append(")");
        String selection = sb.toString();

        int len =
                (columnForExactMatching == null ? 0 : columnForExactMatching.length)
                        + (columnForPartialMatching == null ? 0 : columnForPartialMatching.length);
        String[] selectionArgs = new String[len + 2];
        long now = System.currentTimeMillis();
        selectionArgs[0] = String.valueOf(now + SEARCH_TIME_FRAME_MS);
        selectionArgs[1] = String.valueOf(now);
        insertSelectionArgumentStrings(
                selectionArgs, 2, query, columnForExactMatching, columnForPartialMatching);

        List<SearchResult> searchResults = new ArrayList<>();

        try (Cursor c =
                mContentResolver.query(
                        Programs.CONTENT_URI, projection, selection, selectionArgs, null)) {
            if (c != null) {
                int count = 0;
                while (c.moveToNext()) {
                    long id = c.getLong(0);
                    // Filter out the program whose channel is already searched.
                    if (channelsFound.contains(id)) {
                        continue;
                    }
                    channelsFound.add(id);

                    // Don't know whether the channel is searchable or not.
                    String[] channelProjection = {
                        Channels._ID, Channels.COLUMN_DISPLAY_NUMBER, Channels.COLUMN_DISPLAY_NAME
                    };
                    sb = new StringBuilder();
                    sb.append(Channels._ID)
                            .append("=? AND ")
                            .append(Channels.COLUMN_BROWSABLE)
                            .append("=1 AND ")
                            .append(Channels.COLUMN_SEARCHABLE)
                            .append("=1");
                    if (mTvInputManager.isParentalControlsEnabled()) {
                        sb.append(" AND ").append(Channels.COLUMN_LOCKED).append("=0");
                    }
                    String selectionChannel = sb.toString();
                    try (Cursor cChannel =
                            mContentResolver.query(
                                    Channels.CONTENT_URI,
                                    channelProjection,
                                    selectionChannel,
                                    new String[] {String.valueOf(id)},
                                    null)) {
                        if (cChannel != null
                                && cChannel.moveToNext()
                                && !isRatingBlocked(c.getString(3))) {
                            long startUtcMillis = c.getLong(6);
                            long endUtcMillis = c.getLong(7);
                            SearchResult.Builder result = SearchResult.builder();
                            result.setChannelId(c.getLong(0));
                            result.setTitle(c.getString(1));
                            result.setDescription(
                                    buildProgramDescription(
                                            cChannel.getString(1),
                                            cChannel.getString(2),
                                            startUtcMillis,
                                            endUtcMillis));
                            result.setImageUri(c.getString(2));
                            result.setIntentAction(Intent.ACTION_VIEW);
                            result.setIntentData(buildIntentData(id));
                            result.setIntentExtraData(
                                    TvContract.buildProgramUri(c.getLong(8)).toString());
                            result.setContentType(Programs.CONTENT_ITEM_TYPE);
                            result.setIsLive(true);
                            result.setVideoWidth(c.getInt(4));
                            result.setVideoHeight(c.getInt(5));
                            result.setDuration(endUtcMillis - startUtcMillis);
                            result.setProgressPercentage(
                                    getProgressPercentage(startUtcMillis, endUtcMillis));
                            searchResults.add(result.build());

                            if (limit != NO_LIMIT && ++count >= limit) {
                                break;
                            }
                        }
                    }
                }
            }
        }
        if (DEBUG) {
            Log.d(
                    TAG,
                    "Found "
                            + searchResults.size()
                            + " programs. Elapsed time for searching"
                            + " programs: "
                            + (SystemClock.elapsedRealtime() - time)
                            + "(msec)");
        }
        return searchResults;
    }

    private String buildIntentData(long channelId) {
        return TvContract.buildChannelUri(channelId).toString();
    }

    private boolean isRatingBlocked(String ratings) {
        if (TextUtils.isEmpty(ratings) || !mTvInputManager.isParentalControlsEnabled()) {
            return false;
        }
        ImmutableList<TvContentRating> ratingArray = mTvContentRatingCache.getRatings(ratings);
        if (ratingArray != null) {
            for (TvContentRating r : ratingArray) {
                if (mTvInputManager.isRatingBlocked(r)) {
                    return true;
                }
            }
        }
        return false;
    }

    private List<SearchResult> searchInputs(String query, int limit) {
        if (DEBUG) Log.d(TAG, "Searching inputs: '" + query + "'");
        long time = SystemClock.elapsedRealtime();

        query = canonicalizeLabel(query);
        List<TvInputInfo> inputList = mTvInputManager.getTvInputList();
        List<SearchResult> results = new ArrayList<>();

        // Find exact matches first.
        for (TvInputInfo input : inputList) {
            if (input.getType() == TvInputInfo.TYPE_TUNER) {
                continue;
            }
            String label = canonicalizeLabel(input.loadLabel(mContext));
            String customLabel = canonicalizeLabel(input.loadCustomLabel(mContext));
            if (TextUtils.equals(query, label) || TextUtils.equals(query, customLabel)) {
                results.add(buildSearchResultForInput(input.getId()));
                if (results.size() >= limit) {
                    if (DEBUG) {
                        Log.d(
                                TAG,
                                "Found "
                                        + results.size()
                                        + " inputs. Elapsed time for"
                                        + " searching inputs: "
                                        + (SystemClock.elapsedRealtime() - time)
                                        + "(msec)");
                    }
                    return results;
                }
            }
        }

        // Then look for partial matches.
        for (TvInputInfo input : inputList) {
            if (input.getType() == TvInputInfo.TYPE_TUNER) {
                continue;
            }
            String label = canonicalizeLabel(input.loadLabel(mContext));
            String customLabel = canonicalizeLabel(input.loadCustomLabel(mContext));
            if ((label != null && label.contains(query))
                    || (customLabel != null && customLabel.contains(query))) {
                results.add(buildSearchResultForInput(input.getId()));
                if (results.size() >= limit) {
                    if (DEBUG) {
                        Log.d(
                                TAG,
                                "Found "
                                        + results.size()
                                        + " inputs. Elapsed time for"
                                        + " searching inputs: "
                                        + (SystemClock.elapsedRealtime() - time)
                                        + "(msec)");
                    }
                    return results;
                }
            }
        }
        if (DEBUG) {
            Log.d(
                    TAG,
                    "Found "
                            + results.size()
                            + " inputs. Elapsed time for searching"
                            + " inputs: "
                            + (SystemClock.elapsedRealtime() - time)
                            + "(msec)");
        }
        return results;
    }

    private String canonicalizeLabel(CharSequence cs) {
        Locale locale = mContext.getResources().getConfiguration().locale;
        return cs != null ? cs.toString().replaceAll("[ -]", "").toLowerCase(locale) : null;
    }

    private SearchResult buildSearchResultForInput(String inputId) {
        SearchResult.Builder result = SearchResult.builder();
        result.setIntentAction(Intent.ACTION_VIEW);
        result.setIntentData(TvContract.buildChannelUriForPassthroughInput(inputId).toString());
        return result.build();
    }

    @WorkerThread
    private class ChannelComparatorWithSameDisplayNumber implements Comparator<SearchResult> {
        private final Map<Long, Long> mMaxWatchStartTimeMap = new HashMap<>();

        @Override
        public int compare(SearchResult lhs, SearchResult rhs) {
            // Show recently watched channel first
            Long lhsMaxWatchStartTime = mMaxWatchStartTimeMap.get(lhs.getChannelId());
            if (lhsMaxWatchStartTime == null) {
                lhsMaxWatchStartTime = getMaxWatchStartTime(lhs.getChannelId());
                mMaxWatchStartTimeMap.put(lhs.getChannelId(), lhsMaxWatchStartTime);
            }
            Long rhsMaxWatchStartTime = mMaxWatchStartTimeMap.get(rhs.getChannelId());
            if (rhsMaxWatchStartTime == null) {
                rhsMaxWatchStartTime = getMaxWatchStartTime(rhs.getChannelId());
                mMaxWatchStartTimeMap.put(rhs.getChannelId(), rhsMaxWatchStartTime);
            }
            if (!Objects.equals(lhsMaxWatchStartTime, rhsMaxWatchStartTime)) {
                return Long.compare(rhsMaxWatchStartTime, lhsMaxWatchStartTime);
            }
            // Show recently added channel first if there's no watch history.
            return Long.compare(rhs.getChannelId(), lhs.getChannelId());
        }

        private long getMaxWatchStartTime(long channelId) {
            Uri uri = WatchedPrograms.CONTENT_URI;
            String[] projections =
                    new String[] {
                        "MAX("
                                + WatchedPrograms.COLUMN_START_TIME_UTC_MILLIS
                                + ") AS max_watch_start_time"
                    };
            String selection = WatchedPrograms.COLUMN_CHANNEL_ID + "=?";
            String[] selectionArgs = new String[] {Long.toString(channelId)};
            try (Cursor c =
                    mContentResolver.query(uri, projections, selection, selectionArgs, null)) {
                if (c != null && c.moveToNext()) {
                    return c.getLong(0);
                }
            }
            return -1;
        }
    }
}
