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

import android.accounts.Account;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.test.AndroidTestCase;
import android.test.RenamingDelegatingContext;
import android.test.mock.MockContentResolver;
import android.test.mock.MockContext;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;

import com.android.internal.os.AtomicFile;

import java.io.File;
import java.io.FileOutputStream;

/**
 * Test for SyncStorageEngine.
 *
 * bit FrameworksServicesTests:com.android.server.content.SyncStorageEngineTest
 *
 * TODO Broken.  Fix it.  b/62485315
 */
public class SyncStorageEngineTest extends AndroidTestCase {

    protected Account account1;
    protected Account account2;
    protected ComponentName syncService1;
    protected String authority1 = "testprovider";
    protected Bundle defaultBundle;
    protected final int DEFAULT_USER = 0;

    /* Some default poll frequencies. */
    final long dayPoll = (60 * 60 * 24);
    final long dayFuzz = 60;
    final long thousandSecs = 1000;
    final long thousandSecsFuzz = 100;

    MockContentResolver mockResolver;
    SyncStorageEngine engine;

    private File getSyncDir() {
        return new File(new File(getContext().getFilesDir(), "system"), "sync");
    }

    @Override
    public void setUp() {
        account1 = new Account("a@example.com", "example.type");
        account2 = new Account("b@example.com", "example.type");
        syncService1 = new ComponentName("com.example", "SyncService");
        // Default bundle.
        defaultBundle = new Bundle();
        defaultBundle.putInt("int_key", 0);
        defaultBundle.putString("string_key", "hello");
        // Set up storage engine.
        mockResolver = new MockContentResolver();
        engine = SyncStorageEngine.newTestInstance(
                new TestContext(mockResolver, getContext()));
    }

    /**
     * Test that we handle the case of a history row being old enough to purge before the
     * corresponding sync is finished. This can happen if the clock changes while we are syncing.
     *
     */
    // TODO: this test causes AidlTest to fail. Omit for now
    // @SmallTest
    public void testPurgeActiveSync() throws Exception {
        final Account account = new Account("a@example.com", "example.type");
        final String authority = "testprovider";

        MockContentResolver mockResolver = new MockContentResolver();

        SyncStorageEngine engine = SyncStorageEngine.newTestInstance(
                new TestContext(mockResolver, getContext()));
        long time0 = 1000;
        SyncOperation op = new SyncOperation(account, 0, 0, "foo",
                SyncOperation.REASON_PERIODIC,
                SyncStorageEngine.SOURCE_LOCAL,
                authority,
                Bundle.EMPTY, true);
        long historyId = engine.insertStartSyncEvent(op, time0);
        long time1 = time0 + SyncStorageEngine.MILLIS_IN_4WEEKS * 2;
        engine.stopSyncEvent(historyId, time1 - time0, "yay", 0, 0);
    }

    @LargeTest
    public void testAuthorityPersistence() throws Exception {
        final Account account1 = new Account("a@example.com", "example.type");
        final Account account2 = new Account("b@example.com", "example.type.2");
        final String authority1 = "testprovider1";
        final String authority2 = "testprovider2";

        engine.setMasterSyncAutomatically(false, 0);

        engine.setIsSyncable(account1, 0, authority1, 1);
        engine.setSyncAutomatically(account1, 0, authority1, true);

        engine.setIsSyncable(account2, 0, authority1, 1);
        engine.setSyncAutomatically(account2, 0, authority1, true);

        engine.setIsSyncable(account1, 0, authority2, 1);
        engine.setSyncAutomatically(account1, 0, authority2, false);

        engine.setIsSyncable(account2, 0, authority2, 0);
        engine.setSyncAutomatically(account2, 0, authority2, true);

        engine.writeAllState();
        engine.clearAndReadState();

        assertEquals(true, engine.getSyncAutomatically(account1, 0, authority1));
        assertEquals(true, engine.getSyncAutomatically(account2, 0, authority1));
        assertEquals(false, engine.getSyncAutomatically(account1, 0, authority2));
        assertEquals(true, engine.getSyncAutomatically(account2, 0, authority2));

        assertEquals(1, engine.getIsSyncable(account1, 0, authority1));
        assertEquals(1, engine.getIsSyncable(account2, 0, authority1));
        assertEquals(1, engine.getIsSyncable(account1, 0, authority2));
        assertEquals(0, engine.getIsSyncable(account2, 0, authority2));
    }

    @MediumTest
    public void testListenForTicklesParsing() throws Exception {
        byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
                + "<accounts>\n"
                + "<listenForTickles user=\"0\" enabled=\"false\" />"
                + "<listenForTickles user=\"1\" enabled=\"true\" />"
                + "<authority id=\"0\" user=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\" />\n"
                + "<authority id=\"1\" user=\"1\" account=\"account1\" type=\"type1\" authority=\"auth1\" />\n"
                + "</accounts>\n").getBytes();

        MockContentResolver mockResolver = new MockContentResolver();
        final TestContext testContext = new TestContext(mockResolver, getContext());

        File syncDir = getSyncDir();
        syncDir.mkdirs();
        AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
        FileOutputStream fos = accountInfoFile.startWrite();
        fos.write(accountsFileData);
        accountInfoFile.finishWrite(fos);

        SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext);

        assertEquals(false, engine.getMasterSyncAutomatically(0));
        assertEquals(true, engine.getMasterSyncAutomatically(1));
        assertEquals(true, engine.getMasterSyncAutomatically(2));

    }

    @MediumTest
    public void testAuthorityRenaming() throws Exception {
        final Account account1 = new Account("acc1", "type1");
        final Account account2 = new Account("acc2", "type2");
        final String authorityContacts = "contacts";
        final String authorityCalendar = "calendar";
        final String authorityOther = "other";
        final String authorityContactsNew = "com.android.contacts";
        final String authorityCalendarNew = "com.android.calendar";

        MockContentResolver mockResolver = new MockContentResolver();

        final TestContext testContext = new TestContext(mockResolver, getContext());

        byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
                + "<accounts>\n"
                + "<authority id=\"0\" account=\"acc1\" type=\"type1\" authority=\"contacts\" />\n"
                + "<authority id=\"1\" account=\"acc1\" type=\"type1\" authority=\"calendar\" />\n"
                + "<authority id=\"2\" account=\"acc1\" type=\"type1\" authority=\"other\" />\n"
                + "<authority id=\"3\" account=\"acc2\" type=\"type2\" authority=\"contacts\" />\n"
                + "<authority id=\"4\" account=\"acc2\" type=\"type2\" authority=\"calendar\" />\n"
                + "<authority id=\"5\" account=\"acc2\" type=\"type2\" authority=\"other\" />\n"
                + "<authority id=\"6\" account=\"acc2\" type=\"type2\" enabled=\"false\""
                + " authority=\"com.android.calendar\" />\n"
                + "<authority id=\"7\" account=\"acc2\" type=\"type2\" enabled=\"false\""
                + " authority=\"com.android.contacts\" />\n"
                + "</accounts>\n").getBytes();

        File syncDir = new File(new File(testContext.getFilesDir(), "system"), "sync");
        syncDir.mkdirs();
        AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
        FileOutputStream fos = accountInfoFile.startWrite();
        fos.write(accountsFileData);
        accountInfoFile.finishWrite(fos);

        SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext);

        assertEquals(false, engine.getSyncAutomatically(account1, 0, authorityContacts));
        assertEquals(false, engine.getSyncAutomatically(account1, 0, authorityCalendar));
        assertEquals(true, engine.getSyncAutomatically(account1, 0, authorityOther));
        assertEquals(true, engine.getSyncAutomatically(account1, 0, authorityContactsNew));
        assertEquals(true, engine.getSyncAutomatically(account1, 0, authorityCalendarNew));

        assertEquals(false, engine.getSyncAutomatically(account2, 0, authorityContacts));
        assertEquals(false, engine.getSyncAutomatically(account2, 0, authorityCalendar));
        assertEquals(true, engine.getSyncAutomatically(account2, 0, authorityOther));
        assertEquals(false, engine.getSyncAutomatically(account2, 0, authorityContactsNew));
        assertEquals(false, engine.getSyncAutomatically(account2, 0, authorityCalendarNew));
    }

    @SmallTest
    public void testSyncableMigration() throws Exception {
        final Account account = new Account("acc", "type");

        MockContentResolver mockResolver = new MockContentResolver();

        final TestContext testContext = new TestContext(mockResolver, getContext());

        byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
                + "<accounts>\n"
                + "<authority id=\"0\" account=\"acc\" authority=\"other1\" />\n"
                + "<authority id=\"1\" account=\"acc\" type=\"type\" authority=\"other2\" />\n"
                + "<authority id=\"2\" account=\"acc\" type=\"type\" syncable=\"false\""
                + " authority=\"other3\" />\n"
                + "<authority id=\"3\" account=\"acc\" type=\"type\" syncable=\"true\""
                + " authority=\"other4\" />\n"
                + "</accounts>\n").getBytes();

        File syncDir = new File(new File(testContext.getFilesDir(), "system"), "sync");
        syncDir.mkdirs();
        AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
        FileOutputStream fos = accountInfoFile.startWrite();
        fos.write(accountsFileData);
        accountInfoFile.finishWrite(fos);

        SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext);

        assertEquals(-1, engine.getIsSyncable(account, 0, "other1"));
        assertEquals(1, engine.getIsSyncable(account, 0, "other2"));
        assertEquals(0, engine.getIsSyncable(account, 0, "other3"));
        assertEquals(1, engine.getIsSyncable(account, 0, "other4"));
    }

    /**
     * Verify that the API cannot cause a run-time reboot by passing in the empty string as an
     * authority. The problem here is that
     * {@link SyncStorageEngine#getOrCreateAuthorityLocked(account, provider)} would register
     * an empty authority which causes a RTE in {@link SyncManager#scheduleReadyPeriodicSyncs()}.
     * This is not strictly a SSE test, but it does depend on the SSE data structures.
     */
    @SmallTest
    public void testExpectedIllegalArguments() throws Exception {
        try {
            ContentResolver.setSyncAutomatically(account1, "", true);
            fail("empty provider string should throw IllegalArgumentException");
        } catch (IllegalArgumentException expected) {}

        try {
            ContentResolver.addPeriodicSync(account1, "", Bundle.EMPTY, 84000L);
            fail("empty provider string should throw IllegalArgumentException");
        } catch (IllegalArgumentException expected) {}

        try {
            ContentResolver.removePeriodicSync(account1, "", Bundle.EMPTY);
            fail("empty provider string should throw IllegalArgumentException");
        } catch (IllegalArgumentException expected) {}

        try {
            ContentResolver.cancelSync(account1, "");
            fail("empty provider string should throw IllegalArgumentException");
        } catch (IllegalArgumentException expected) {}

        try {
            ContentResolver.setIsSyncable(account1, "", 0);
            fail("empty provider string should throw IllegalArgumentException");
        } catch (IllegalArgumentException expected) {}

        try {
            ContentResolver.cancelSync(account1, "");
            fail("empty provider string should throw IllegalArgumentException");
        } catch (IllegalArgumentException expected) {}

        try {
            ContentResolver.requestSync(account1, "", Bundle.EMPTY);
            fail("empty provider string should throw IllegalArgumentException");
        } catch (IllegalArgumentException expected) {}

        try {
            ContentResolver.getSyncStatus(account1, "");
            fail("empty provider string should throw IllegalArgumentException");
        } catch (IllegalArgumentException expected) {}

        // Make sure we aren't blocking null account/provider for those functions that use it
        // to specify ALL accounts/providers.
        ContentResolver.requestSync(null, null, Bundle.EMPTY);
        ContentResolver.cancelSync(null, null);
    }
}

class TestContext extends ContextWrapper {

    ContentResolver mResolver;

    private final Context mRealContext;

    public TestContext(ContentResolver resolver, Context realContext) {
        super(new RenamingDelegatingContext(new MockContext(), realContext, "test."));
        mRealContext = realContext;
        mResolver = resolver;
    }

    @Override
    public Resources getResources() {
        return mRealContext.getResources();
    }

    @Override
    public File getFilesDir() {
        return mRealContext.getFilesDir();
    }

    @Override
    public void enforceCallingOrSelfPermission(String permission, String message) {
    }

    @Override
    public void sendBroadcast(Intent intent) {
    }

    @Override
    public ContentResolver getContentResolver() {
        return mResolver;
    }
}
