/*
 * Copyright (C) 2014 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.providers.tv;

import com.google.android.collect.Sets;

import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.ProviderInfo;
import android.database.Cursor;
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.net.Uri;
import android.os.Bundle;
import android.os.SystemClock;
import android.provider.Settings;
import android.test.ServiceTestCase;
import android.test.mock.MockContentProvider;
import android.test.mock.MockContentResolver;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

public class EpgDataCleanupServiceTests extends ServiceTestCase<EpgDataCleanupService> {
    private static final String FAKE_INPUT_ID = "EpgDataCleanupServiceTests";

    private MockContentResolver mResolver;
    private TvProvider mProvider;

    public EpgDataCleanupServiceTests() {
        super(EpgDataCleanupService.class);
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();

        mResolver = new MockContentResolver();
        // DateUtils tries to access Settings provider to get date format string.
        mResolver.addProvider(Settings.AUTHORITY, new MockContentProvider() {
            @Override
            public Bundle call(String method, String request, Bundle args) {
                return new Bundle();
            }
        });

        mProvider = new TvProviderForTesting();
        mResolver.addProvider(TvContract.AUTHORITY, mProvider);

        setContext(new MockTvProviderContext(mResolver, getSystemContext()));

        final ProviderInfo info = new ProviderInfo();
        info.authority = TvContract.AUTHORITY;
        mProvider.attachInfoForTesting(getContext(), info);

        startService(new Intent(getContext(), EpgDataCleanupService.class));
    }

    @Override
    protected void tearDown() throws Exception {
        mProvider.shutdown();
        super.tearDown();
    }

    private static class Program {
        long id;
        final long startTime;
        final long endTime;

        Program(long startTime, long endTime) {
            this(-1, startTime, endTime);
        }

        Program(long id, long startTime, long endTime) {
            this.id = id;
            this.startTime = startTime;
            this.endTime = endTime;
        }

        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof Program)) {
                return false;
            }
            Program that = (Program) obj;
            return Objects.equals(id, that.id)
                    && Objects.equals(startTime, that.startTime)
                    && Objects.equals(endTime, that.endTime);
        }

        @Override
        public int hashCode() {
            return Objects.hash(id, startTime, endTime);
        }

        @Override
        public String toString() {
            return "Program(id=" + id + ",start=" + startTime + ",end=" + endTime + ")";
        }
    }

    private long insertChannel() {
        ContentValues values = new ContentValues();
        values.put(Channels.COLUMN_INPUT_ID, FAKE_INPUT_ID);
        Uri uri = mResolver.insert(Channels.CONTENT_URI, values);
        assertNotNull(uri);
        return ContentUris.parseId(uri);
    }

    private void insertPrograms(Program... programs) {
        insertPrograms(Arrays.asList(programs));
    }

    private void insertPrograms(Collection<Program> programs) {
        long channelId = insertChannel();

        ContentValues values = new ContentValues();
        values.put(Programs.COLUMN_CHANNEL_ID, channelId);
        for (Program program : programs) {
            values.put(Programs.COLUMN_START_TIME_UTC_MILLIS, program.startTime);
            values.put(Programs.COLUMN_END_TIME_UTC_MILLIS, program.endTime);
            Uri uri = mResolver.insert(Programs.CONTENT_URI, values);
            assertNotNull(uri);
            program.id = ContentUris.parseId(uri);
        }
    }

    private Set<Program> queryPrograms() {
        String[] projection = new String[] {
            Programs._ID,
            Programs.COLUMN_START_TIME_UTC_MILLIS,
            Programs.COLUMN_END_TIME_UTC_MILLIS,
        };

        Cursor cursor = mResolver.query(Programs.CONTENT_URI, projection, null, null, null);
        assertNotNull(cursor);
        try {
            Set<Program> programs = Sets.newHashSet();
            while (cursor.moveToNext()) {
                programs.add(new Program(cursor.getLong(0), cursor.getLong(1), cursor.getLong(2)));
            }
            return programs;
        } finally {
            cursor.close();
        }
    }

    private void insertWatchedPrograms(Program... programs) {
        insertWatchedPrograms(Arrays.asList(programs));
    }

    private void insertWatchedPrograms(Collection<Program> programs) {
        long channelId = insertChannel();

        ContentValues values = new ContentValues();
        values.put(WatchedPrograms.COLUMN_PACKAGE_NAME, getContext().getPackageName());
        values.put(WatchedPrograms.COLUMN_CHANNEL_ID, channelId);
        for (Program program : programs) {
            values.put(WatchedPrograms.COLUMN_WATCH_START_TIME_UTC_MILLIS, program.startTime);
            values.put(WatchedPrograms.COLUMN_WATCH_END_TIME_UTC_MILLIS, program.endTime);
            Uri uri = mResolver.insert(WatchedPrograms.CONTENT_URI, values);
            assertNotNull(uri);
            program.id = ContentUris.parseId(uri);
        }
    }

    private Set<Program> queryWatchedPrograms() {
        String[] projection = new String[] {
            WatchedPrograms._ID,
            WatchedPrograms.COLUMN_WATCH_START_TIME_UTC_MILLIS,
            WatchedPrograms.COLUMN_WATCH_END_TIME_UTC_MILLIS,
        };

        Cursor cursor = mResolver.query(WatchedPrograms.CONTENT_URI, projection, null, null, null);
        assertNotNull(cursor);
        try {
            Set<Program> programs = Sets.newHashSet();
            while (cursor.moveToNext()) {
                programs.add(new Program(cursor.getLong(0), cursor.getLong(1), cursor.getLong(2)));
            }
            return programs;
        } finally {
            cursor.close();
        }
    }

    @Override
    public void testServiceTestCaseSetUpProperly() throws Exception {
        assertNotNull(getService());
    }

    public void testClearOldPrograms() {
        Program program = new Program(1, 2);
        insertPrograms(program);

        getService().clearOldPrograms(2);
        assertEquals("Program should NOT be deleted if it ended at given time.",
                Sets.newHashSet(program), queryPrograms());

        getService().clearOldPrograms(3);
        assertTrue("Program should be deleted if it ended before given time.",
                queryPrograms().isEmpty());

        ArrayList<Program> programs = new ArrayList<Program>();
        for (int i = 0; i < 10; i++) {
            programs.add(new Program(999 + i, 1000 + i));
        }
        insertPrograms(programs);

        getService().clearOldPrograms(1005);
        assertEquals("Program should be deleted if and only if it ended before given time.",
                new HashSet<Program>(programs.subList(5, 10)), queryPrograms());
    }

    public void testClearOldWatchedPrograms() {
        Program program = new Program(1, 2);
        insertWatchedPrograms(program);

        getService().clearOldWatchHistory(1);
        assertEquals("Watch history should NOT be deleted if watch started at given time.",
                Sets.newHashSet(program), queryWatchedPrograms());

        getService().clearOldWatchHistory(2);
        assertTrue("Watch history shuold be deleted if watch started before given time.",
                queryWatchedPrograms().isEmpty());

        ArrayList<Program> programs = new ArrayList<Program>();
        for (int i = 0; i < 10; i++) {
            programs.add(new Program(1000 + i, 1001 + i));
        }
        insertWatchedPrograms(programs);

        getService().clearOldWatchHistory(1005);
        assertEquals("Watch history should be deleted if and only if it started before given time.",
                new HashSet<Program>(programs.subList(5, 10)), queryWatchedPrograms());
    }

    public void testClearOverflowWatchHistory() {
        ArrayList<Program> programs = new ArrayList<Program>();
        for (int i = 0; i < 10; i++) {
            programs.add(new Program(1000 + i, 1001 + i));
        }
        insertWatchedPrograms(programs);

        getService().clearOverflowWatchHistory(5);
        assertEquals("Watch history should be deleted in watch start time order.",
                new HashSet<Program>(programs.subList(5, 10)), queryWatchedPrograms());

        getService().clearOverflowWatchHistory(0);
        assertTrue("All history should be deleted.", queryWatchedPrograms().isEmpty());
    }
}
