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

import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.SQLException;
import android.net.Uri;
import android.os.Handler;
import android.provider.Telephony.CarrierId;
import android.telephony.SubscriptionManager;
import android.test.mock.MockContentResolver;
import android.test.mock.MockContext;
import android.util.Log;

import junit.framework.TestCase;

import org.junit.Assert;
import org.junit.Test;

import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

/**
 * Tests for testing CRUD operations of CarrierIdProvider.
 * Uses CarrierIdProviderTestable to set up in-memory database
 *
 * Build, install and run the tests by running the commands below:
 *     runtest --path <dir or file>
 *     runtest --path <dir or file> --test-method <testMethodName>
 *     e.g.)
 *         runtest --path tests/src/com/android/providers/telephony/CarrierIdProviderTest.java \
 *                 --test-method testInsertCarrierInfo
 */
public class CarrierIdProviderTest extends TestCase {

    private static final String TAG = CarrierIdProviderTest.class.getSimpleName();

    private static final String test_mccmnc = "MCCMNC_TEST";
    private static final String test_gid1 = "GID1_TEST";
    private static final String test_gid2 = "GID2_TEST";
    private static final String test_plmn = "PLMN_TEST";
    private static final String test_imsi_prefix = "IMSI_PREFIX_TEST";
    private static final String test_spn = "SPN_TEST";
    private static final String test_apn = "APN_TEST";
    private static final String test_iccid_prefix = "ICCID_PREFIX_TEST";
    private static final String test_name = "NAME_TEST";
    private static final String test_access_rule =
            "B9CFCE1C47A6AC713442718F15EF55B00B3A6D1A6D48CB46249FA8EB51465350";
    private static final int test_cid = 0;

    private MockContextWithProvider mContext;
    private MockContentResolver mContentResolver;
    private CarrierIdProviderTestable mCarrierIdProviderTestable;
    private FakeContentObserver mContentObserver;
    private SharedPreferences mSharedPreferences = mock(SharedPreferences.class);
    private SubscriptionManager subscriptionManager = mock(SubscriptionManager.class);

    private class FakeContentResolver extends MockContentResolver {
        @Override
        public void notifyChange(Uri uri, ContentObserver observer) {
            super.notifyChange(uri, observer);
            Log.d(TAG, "onChanged(uri=" + uri + ")" + observer);
            mContentObserver.dispatchChange(false, uri);
        }
    }

    private class FakeContentObserver extends ContentObserver {
        private boolean changed = false;
        private FakeContentObserver(Handler handler) {
            super(handler);
        }
        @Override
        public void onChange(boolean selfChange) {
            changed = true;
        }
    }

    /**
     * This is used to give the CarrierIdProviderTest a mocked context which takes a
     * CarrierIdProvider and attaches it to the ContentResolver.
     */
    private class MockContextWithProvider extends MockContext {
        private final MockContentResolver mResolver;

        public MockContextWithProvider(CarrierIdProviderTestable carrierIdProvider) {
            mResolver = new FakeContentResolver();

            carrierIdProvider.initializeForTesting(this);
            Log.d(TAG, "MockContextWithProvider: carrierIdProvider.getContext(): "
                    + carrierIdProvider.getContext());

            // Add given carrierIdProvider to mResolver, so that mResolver can send queries
            // to the provider.
            mResolver.addProvider(CarrierIdProvider.AUTHORITY, carrierIdProvider);
            Log.d(TAG, "MockContextWithProvider: Add carrierIdProvider to mResolver");
        }

        @Override
        public Object getSystemService(String name) {
            switch (name) {
                case Context.TELEPHONY_SUBSCRIPTION_SERVICE:
                    return subscriptionManager;
                default:
                    Log.d(TAG, "getSystemService: returning null");
                    return null;
            }
        }

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

        @Override
        public int checkCallingOrSelfPermission(String permission) {
            return PackageManager.PERMISSION_GRANTED;
        }

        @Override
        public SharedPreferences getSharedPreferences(String name, int mode) {
            return mSharedPreferences;
        }
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        mCarrierIdProviderTestable = new CarrierIdProviderTestable();
        mContext = new MockContextWithProvider(mCarrierIdProviderTestable);
        mContentResolver = mContext.getContentResolver();
        mContentObserver = new FakeContentObserver(null);
    }

    @Override
    protected void tearDown() throws Exception {
        mCarrierIdProviderTestable.closeDatabase();
        super.tearDown();
    }

    /**
     * Test inserting values in carrier identification table.
     */
    @Test
    public void testInsertCarrierInfo() {
        try {
            mContentResolver.insert(CarrierId.All.CONTENT_URI, createCarrierInfoInternal());
            Cursor countCursor = mContentResolver.query(CarrierId.All.CONTENT_URI,
                    new String[]{"count(*) AS count"},
                    null,
                    null,
                    null);
            countCursor.moveToFirst();
            assertEquals(1, countCursor.getInt(0));
            assertTrue(mContentObserver.changed);
        } catch (Exception e) {
            Log.d(TAG, "Error inserting carrier info:" + e);
        }
    }

    /**
     * Test invalid insertion of duplicate info
     */
    @Test
    public void testDuplicateInsertionCarrierInfo() {
        try {
            //insert same row twice to break uniqueness constraint
            ContentValues contentValues = createCarrierInfoInternal();
            mContentResolver.insert(CarrierId.All.CONTENT_URI, contentValues);
            mContentResolver.insert(CarrierId.All.CONTENT_URI, contentValues);
            Assert.fail("should throw an exception for duplicate carrier info");
        } catch (Exception e) {
            Log.d(TAG, "Error inserting carrier info:" + e);
        }
    }

    /**
     * Test invalid insertion of null mccmnc
     */
    @Test
    public void testInvalidInsertionCarrierInfo() {
        try {
            //insert a row with null mnccmnc to break not null constraint
            ContentValues contentValues = new ContentValues();
            contentValues.put(CarrierId.All.GID1, test_gid1);
            mContentResolver.insert(CarrierId.All.CONTENT_URI, contentValues);
            Assert.fail("should throw an exception for null mccmnc");
        } catch (SQLException e) {
            Log.d(TAG, "Error inserting carrier info:" + e);
            assertFalse(mContentObserver.changed);
        }
    }

    /**
     * Test delete.
     */
    @Test
    public void testDeleteCarrierInfo() {
        try {
            mContentResolver.insert(CarrierId.All.CONTENT_URI,
                    createCarrierInfoInternal());
        } catch (Exception e) {
            Log.d(TAG, "Error inserting carrier info:" + e);
        }
        int numRowsDeleted = -1;
        try {
            String whereClause = CarrierId.All.MCCMNC + "=?";
            String[] whereArgs = new String[] { test_mccmnc };
            numRowsDeleted = mContentResolver.delete(CarrierId.All.CONTENT_URI,
                    whereClause, whereArgs);
        } catch (Exception e) {
            Log.d(TAG, "Error deleting values:" + e);
        }
        assertEquals(1, numRowsDeleted);
        assertTrue(mContentObserver.changed);
    }

    /**
     * Test update & query.
     */
    @Test
    public void testUpdateCarrierInfo() {
        int cid = -1;
        ContentValues contentValues = createCarrierInfoInternal();

        try {
            mContentResolver.insert(CarrierId.All.CONTENT_URI, contentValues);
        } catch (Exception e) {
            Log.d(TAG, "Error inserting carrierInfo:" + e);
        }

        try {
            contentValues.put(CarrierId.CARRIER_ID, 1);
            mContentResolver.update(CarrierId.All.CONTENT_URI, contentValues,
                    CarrierId.All.MCCMNC + "=?", new String[] { test_mccmnc });
        } catch (Exception e) {
            Log.d(TAG, "Error updating values:" + e);
        }

        try {
            Cursor findEntry = mContentResolver.query(CarrierId.All.CONTENT_URI,
                    new String[] { CarrierId.CARRIER_ID},
                    CarrierId.All.MCCMNC + "=?", new String[] { test_mccmnc },
                    null);
            findEntry.moveToFirst();
            cid = findEntry.getInt(0);
        } catch (Exception e) {
            Log.d(TAG, "Query failed:" + e);
        }
        assertEquals(1, cid);
        assertTrue(mContentObserver.changed);
    }

    @Test
    public void testMultiRowInsertionQuery() {
        ContentValues contentValues = createCarrierInfoInternal();

        try {
            // insert a MVNO
            mContentResolver.insert(CarrierId.All.CONTENT_URI, contentValues);
            // insert its MNO
            contentValues = new ContentValues();
            contentValues.put(CarrierId.All.MCCMNC, test_mccmnc);
            contentValues.put(CarrierId.CARRIER_ID, 1);
            mContentResolver.insert(CarrierId.All.CONTENT_URI, contentValues);
        } catch (Exception e) {
            Log.d(TAG, "Error inserting carrierInfo:" + e);
        }

        Cursor findEntry = null;
        String[] columns = {CarrierId.CARRIER_ID, CarrierId.All.ICCID_PREFIX};
        try {
            findEntry = mContentResolver.query(CarrierId.All.CONTENT_URI, columns,
                    CarrierId.All.MCCMNC + "=?", new String[] { test_mccmnc },
                    null);
        } catch (Exception e) {
            Log.d(TAG, "Query failed:" + e);
        }
        assertEquals(2, findEntry.getCount());

        try {
            // query based on mccmnc & gid1 & iccid_prefix
            findEntry = mContentResolver.query(CarrierId.All.CONTENT_URI, columns,
                    CarrierId.All.MCCMNC + "=? and "
                    + CarrierId.All.GID1 + "=? and "
                    + CarrierId.All.ICCID_PREFIX + "=?",
                    new String[] { test_mccmnc, test_gid1, test_iccid_prefix }, null);
        } catch (Exception e) {
            Log.d(TAG, "Query failed:" + e);
        }
        assertEquals(1, findEntry.getCount());
        findEntry.moveToFirst();
        assertEquals(test_cid, findEntry.getInt(0));
        assertEquals(test_iccid_prefix, findEntry.getString(1));
    }

    @Test
    public void testGetVersion() {
        doReturn(5).when(mSharedPreferences).getInt(eq("version"), anyInt());
        int version = 0;
        try {
            Cursor cursor = mContext.getContentResolver().query(
                    Uri.withAppendedPath(CarrierId.All.CONTENT_URI,
                            "get_version"), null, null, null);
            cursor.moveToFirst();
            version = cursor.getInt(0);
        } catch (Exception e) {
            Log.d(TAG, "Error querying carrier list version:" + e);
        }
        assertEquals(5, version);
    }

    @Test
    public void testUpdateCurrentSubscription() {
        // update carrier id for subId 1
        try {
            ContentValues cv = new ContentValues();
            cv.put(CarrierId.CARRIER_ID, test_cid);
            cv.put(CarrierId.CARRIER_NAME, test_name);
            when(subscriptionManager.isActiveSubscriptionId(eq(1))).thenReturn(true);
            mContext.getContentResolver().update(Uri.withAppendedPath(CarrierId.CONTENT_URI,
                    "1"), cv, null, null);
        } catch (Exception e) {
            Log.d(TAG, "Error updating current subscription: " + e);
            e.printStackTrace();
        }
        int carrierId = -1;
        String carrierName = null;
        // query carrier id for subId 1
        try {
            final Cursor c = mContext.getContentResolver().query(
                    Uri.withAppendedPath(CarrierId.CONTENT_URI, "1"),
                    new String[] {CarrierId.CARRIER_ID, CarrierId.CARRIER_NAME}, null, null);
            c.moveToFirst();
            carrierId = c.getInt(0);
            carrierName = c.getString(1);
        } catch (Exception e) {
            Log.d(TAG, "Error query current subscription: " + e);
        }
        assertEquals(test_cid, carrierId);
        assertEquals(test_name, carrierName);

        // query carrier id for subId 2
        int count  = -1;
        try {
            final Cursor c = mContext.getContentResolver().query(
                    Uri.withAppendedPath(CarrierId.CONTENT_URI, "2"),
                    new String[]{CarrierId.CARRIER_ID, CarrierId.CARRIER_NAME}, null, null);
            count = c.getCount();
        } catch (Exception e) {
            Log.d(TAG, "Error query current subscription: " + e);
        }
        assertEquals(0, count);

        // query without subId, expect return carrier id of the default subId
        try {
            final Cursor c = mContext.getContentResolver().query(CarrierId.CONTENT_URI,
                    new String[]{CarrierId.CARRIER_ID, CarrierId.CARRIER_NAME}, null, null);
            c.moveToFirst();
            carrierId = c.getInt(0);
            carrierName = c.getString(1);
        } catch (Exception e) {
            Log.d(TAG, "Error query current subscription: " + e);
        }
        assertEquals(test_cid, carrierId);
        assertEquals(test_name, carrierName);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testQueryCurrrentSubscription_wrongProjection() {
        mContext.getContentResolver().query(CarrierId.CONTENT_URI,
                new String[]{CarrierId.CARRIER_ID, CarrierId.CARRIER_NAME, CarrierId.All.MCCMNC},
                null, null);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testQueryWithWrongURI() {
        try {
            mContext.getContentResolver().query(Uri.withAppendedPath(
                    CarrierId.CONTENT_URI, "invalid"),
                    new String[]{CarrierId.CARRIER_ID, CarrierId.CARRIER_NAME}, null, null);
            Assert.fail("should throw an exception for wrong uri");
        } catch (IllegalArgumentException ex) {
        }
    }

    @Test(expected = IllegalArgumentException.class)
    public void testUpdateCurrentSubscription_WrongURI() {
        try {
            ContentValues cv = new ContentValues();
            cv.put(CarrierId.CARRIER_ID, test_cid);
            cv.put(CarrierId.CARRIER_NAME, test_name);
            mContext.getContentResolver().update(CarrierId.CONTENT_URI, cv, null, null);
            Assert.fail("should throw an exception for wrong uri");
        } catch (IllegalArgumentException ex) {
            assertFalse(mContentObserver.changed);
        }
    }

    private static ContentValues createCarrierInfoInternal() {
        ContentValues contentValues = new ContentValues();
        contentValues.put(CarrierId.All.MCCMNC, test_mccmnc);
        contentValues.put(CarrierId.All.GID1, test_gid1);
        contentValues.put(CarrierId.All.GID2, test_gid2);
        contentValues.put(CarrierId.All.PLMN, test_plmn);
        contentValues.put(CarrierId.All.IMSI_PREFIX_XPATTERN, test_imsi_prefix);
        contentValues.put(CarrierId.All.SPN, test_spn);
        contentValues.put(CarrierId.All.APN, test_apn);
        contentValues.put(CarrierId.All.ICCID_PREFIX, test_iccid_prefix);
        contentValues.put(CarrierId.CARRIER_NAME, test_name);
        contentValues.put(CarrierId.CARRIER_ID, test_cid);
        contentValues.put(CarrierId.All.PRIVILEGE_ACCESS_RULE, test_access_rule);
        return contentValues;
    }
}
