/*
 * 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 android.carrierapi.cts;

import static junit.framework.TestCase.assertEquals;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.provider.Telephony.Carriers;
import android.util.Log;

import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * Build, install and run the tests by running the commands below:
 *  make cts -j64
 *  cts-tradefed run cts -m CtsCarrierApiTestCases --test android.carrierapi.cts.ApnDatabaseTest
 */
@RunWith(AndroidJUnit4.class)
public class ApnDatabaseTest {
    private static final String TAG = "ApnDatabaseTest";

    private ContentResolver mContentResolver;
    private PackageManager mPackageManager;
    private boolean mHasCellular;

    private static final String NAME = "carrierName";
    private static final String APN = "apn";
    private static final String PROXY = "proxy";
    private static final String PORT = "port";
    private static final String MMSC = "mmsc";
    private static final String MMSPROXY = "mmsproxy";
    private static final String MMSPORT = "mmsport";
    private static final String NUMERIC = "numeric";
    private static final String USER = "user";
    private static final String PASSWORD = "password";
    private static final String AUTH_TYPE = "auth_type";
    private static final String TYPE = "type";
    private static final String PROTOCOL = "protocol";
    private static final String ROAMING_PROTOCOL = "roaming_protocol";
    private static final String CARRIER_ENABLED = "true";
    private static final String NETWORK_TYPE_BITMASK = "0";
    private static final String BEARER = "0";

    private static final Map<String, String> APN_MAP = new HashMap<String,String>() {{
        put(Carriers.NAME, NAME);
        put(Carriers.APN, APN);
        put(Carriers.PROXY, PROXY);
        put(Carriers.PORT, PORT);
        put(Carriers.MMSC, MMSC);
        put(Carriers.MMSPROXY, MMSPROXY);
        put(Carriers.MMSPORT, MMSPORT);
        put(Carriers.NUMERIC, NUMERIC);
        put(Carriers.USER, USER);
        put(Carriers.PASSWORD, PASSWORD);
        put(Carriers.AUTH_TYPE, AUTH_TYPE);
        put(Carriers.TYPE, TYPE);
        put(Carriers.PROTOCOL, PROTOCOL);
        put(Carriers.ROAMING_PROTOCOL, ROAMING_PROTOCOL);
        put(Carriers.CARRIER_ENABLED, CARRIER_ENABLED);
        put(Carriers.NETWORK_TYPE_BITMASK, NETWORK_TYPE_BITMASK);
        put(Carriers.BEARER, BEARER);
    }};

    // Faked network type bitmask and its compatible bearer bitmask.
    private static final int NETWORK_TYPE_BITMASK_NUMBER = 1 << (13 - 1);
    private static final int RIL_RADIO_TECHNOLOGY_BITMASK_NUMBER = 1 << (14 - 1);

    @Before
    public void setUp() throws Exception {
        mContentResolver = InstrumentationRegistry.getContext().getContentResolver();
        mPackageManager = InstrumentationRegistry.getContext().getPackageManager();
        // Checks whether the cellular stack should be running on this device.
        mHasCellular = mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
        if (!mHasCellular) {
            Log.e(TAG, "No cellular support, all tests will be skipped.");
        }
    }

    private void failMessage() {
        fail("This test requires a SIM card with carrier privilege rule on it.\n" +
                "Visit https://source.android.com/devices/tech/config/uicc.html");
    }

    /**
     * Test inserting, querying, updating and deleting values in carriers table.
     * Verify that the inserted values match the result of the query and are deleted.
     */
    @Test
    public void testValidCase() {
        if (!mHasCellular) return;
        Uri uri = Carriers.CONTENT_URI;
        // CONTENT_URI = Uri.parse("content://telephony/carriers");
        // Create A set of column_name/value pairs to add to the database.
        ContentValues contentValues = makeDefaultContentValues();

        try {
            // Insert the value into database.
            Log.d(TAG, "testInsertCarriers Inserting contentValues: " + contentValues.toString());
            Uri newUri = mContentResolver.insert(uri, contentValues);
            assertNotNull("Failed to insert to table", newUri);

            // Get the values in table.
            final String selection = Carriers.NUMERIC + "=?";
            String[] selectionArgs = { NUMERIC };
            String[] apnProjection = APN_MAP.keySet().toArray(new String[APN_MAP.size()]);
            Log.d(TAG, "testInsertCarriers query projection: " + Arrays.toString(apnProjection)
                    + "\ntestInsertCarriers selection: " + selection
                    + "\ntestInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
            Cursor cursor = mContentResolver.query(
                    uri, apnProjection, selection, selectionArgs, null);

            // Verify that the inserted value match the results of the query
            assertNotNull("Failed to query the table", cursor);
            assertEquals("Unexpected number of APNs returned by cursor",
                    1, cursor.getCount());
            cursor.moveToFirst();
            for (Map.Entry<String, String> entry: APN_MAP.entrySet()) {
                assertEquals(
                        "Unexpected value returned by cursor",
                        cursor.getString(cursor.getColumnIndex(entry.getKey())), entry.getValue());
            }

            // update the apn
            final String newApn = "newapn";
            Log.d(TAG, "Update the APN field to: " + newApn);
            contentValues.put(Carriers.APN, newApn);
            final int updateCount = mContentResolver.update(uri, contentValues, selection,
                    selectionArgs);
            assertEquals("Unexpected number of rows updated", 1, updateCount);

            // Verify the updated value
            cursor = mContentResolver.query(uri, apnProjection, selection, selectionArgs, null);
            assertNotNull("Failed to query the table", cursor);
            assertEquals("Unexpected number of APNs returned by cursor", 1, cursor.getCount());
            cursor.moveToFirst();
            assertEquals("Unexpected value returned by cursor",
                    cursor.getString(cursor.getColumnIndex(Carriers.APN)), newApn);

            // delete test content
            final String selectionToDelete = Carriers.NUMERIC + "=?";
            String[] selectionArgsToDelete = { NUMERIC };
            Log.d(TAG, "testInsertCarriers deleting selection: " + selectionToDelete
                    + "testInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
            int numRowsDeleted = mContentResolver.delete(
                    uri, selectionToDelete, selectionArgsToDelete);
            assertEquals("Unexpected number of rows deleted",1, numRowsDeleted);

            // verify that deleted values are gone
            cursor = mContentResolver.query(uri, apnProjection, selection, selectionArgs, null);
            assertEquals("Unexpected number of rows deleted", 0, cursor.getCount());
        } catch (SecurityException e) {
            failMessage();
        }
    }

    @Test
    public void testQueryConflictCase() {
        if (!mHasCellular) return;
        String invalidColumn = "random";
        Uri uri = Carriers.CONTENT_URI;
        // CONTENT_URI = Uri.parse("content://telephony/carriers");
        // Create A set of column_name/value pairs to add to the database.
        ContentValues contentValues = new ContentValues();
        contentValues.put(Carriers.NAME, NAME);
        contentValues.put(Carriers.APN, APN);
        contentValues.put(Carriers.PORT, PORT);
        contentValues.put(Carriers.PROTOCOL, PROTOCOL);
        contentValues.put(Carriers.NUMERIC, NUMERIC);

        try {
            // Insert the value into database.
            Log.d(TAG, "testInsertCarriers Inserting contentValues: " + contentValues.toString());
            Uri newUri = mContentResolver.insert(uri, contentValues);
            assertNotNull("Failed to insert to table", newUri);

            // Try to get the value with invalid selection
            final String[] testProjection =
                    {
                            Carriers.NAME,
                            Carriers.APN,
                            Carriers.PORT,
                            Carriers.PROTOCOL,
                            Carriers.NUMERIC,
                    };
            final String selection = invalidColumn + "=?";
            String[] selectionArgs = { invalidColumn };
            Log.d(TAG, "testInsertCarriers query projection: " + Arrays.toString(testProjection)
                    + "\ntestInsertCarriers selection: " + selection
                    + "\ntestInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
            Cursor cursor = mContentResolver.query(
                    uri, testProjection, selection, selectionArgs, null);
            assertNull("Failed to query the table",cursor);

            // delete test content
            final String selectionToDelete = Carriers.NAME + "=?";
            String[] selectionArgsToDelete = { NAME };
            Log.d(TAG, "testInsertCarriers deleting selection: " + selectionToDelete
                    + "testInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
            int numRowsDeleted = mContentResolver.delete(
                    uri, selectionToDelete, selectionArgsToDelete);
            assertEquals("Unexpected number of rows deleted", 1, numRowsDeleted);

            // verify that deleted values are gone
            cursor = mContentResolver.query(
                    uri, testProjection, selectionToDelete, selectionArgsToDelete, null);
            assertEquals("Unexpected number of rows deleted", 0, cursor.getCount());
        } catch (SecurityException e) {
            failMessage();
        }
    }

    @Test
    public void testUpdateConflictCase() {
        if (!mHasCellular) return;
        Uri uri = Carriers.CONTENT_URI;
        // CONTENT_URI = Uri.parse("content://telephony/carriers");
        // Create A set of column_name/value pairs to add to the database.
        ContentValues contentValues = new ContentValues();
        contentValues.put(Carriers.NAME, NAME);
        contentValues.put(Carriers.APN, APN);
        contentValues.put(Carriers.PORT, PORT);
        contentValues.put(Carriers.PROTOCOL, PROTOCOL);
        contentValues.put(Carriers.NUMERIC, NUMERIC);

        try {
            // Insert the value into database.
            Log.d(TAG, "testInsertCarriers Inserting contentValues: " + contentValues.toString());
            Uri newUri = mContentResolver.insert(uri, contentValues);
            assertNotNull("Failed to insert to table", newUri);

            // Try to get the value with invalid selection
            final String[] testProjection =
                    {
                            Carriers.NAME,
                            Carriers.APN,
                            Carriers.PORT,
                            Carriers.PROTOCOL,
                            Carriers.NUMERIC,
                    };
            String selection = Carriers.NAME + "=?";
            String[] selectionArgs = { NAME };
            Log.d(TAG, "testInsertCarriers query projection: " + Arrays.toString(testProjection)
                    + "\ntestInsertCarriers selection: " + selection
                    + "\ntestInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
            Cursor cursor = mContentResolver.query(
                    uri, testProjection, selection, selectionArgs, null);
            assertEquals("Unexpected number of APNs returned by cursor",
                    1, cursor.getCount());

            // Update the table with invalid column
            String invalidColumn = "random";
            contentValues.put(invalidColumn, invalidColumn);
            try {
                mContentResolver.update(uri, contentValues, selection, selectionArgs);
                fail();
            } catch (SQLiteException e) {
                // Expected: If there's no such a column, an exception will be thrown and the
                // Activity Manager will kill this process shortly.
            }

            // delete test content
            final String selectionToDelete = Carriers.NAME + "=?";
            String[] selectionArgsToDelete = { NAME };
            Log.d(TAG, "testInsertCarriers deleting selection: " + selectionToDelete
                    + "testInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
            int numRowsDeleted = mContentResolver.delete(
                    uri, selectionToDelete, selectionArgsToDelete);
            assertEquals("Unexpected number of rows deleted", 1, numRowsDeleted);

            // verify that deleted values are gone
            cursor = mContentResolver.query(
                    uri, testProjection, selectionToDelete, selectionArgsToDelete, null);
            assertEquals("Unexpected number of rows deleted", 0, cursor.getCount());
        } catch (SecurityException e) {
            failMessage();
        }
    }

    @Test
    public void testDeleteConflictCase() {
        if (!mHasCellular) return;
        String invalidColumn = "random";
        Uri uri = Carriers.CONTENT_URI;
        // CONTENT_URI = Uri.parse("content://telephony/carriers");
        // Create A set of column_name/value pairs to add to the database.
        ContentValues contentValues = new ContentValues();
        contentValues.put(Carriers.NAME, NAME);
        contentValues.put(Carriers.APN, APN);
        contentValues.put(Carriers.PORT, PORT);
        contentValues.put(Carriers.PROTOCOL, PROTOCOL);
        contentValues.put(Carriers.NUMERIC, NUMERIC);

        try {
            // Insert the value into database.
            Log.d(TAG, "testInsertCarriers Inserting contentValues: " + contentValues.toString());
            Uri newUri = mContentResolver.insert(uri, contentValues);
            assertNotNull("Failed to insert to table", newUri);

            // Get the values in table.
            final String[] testProjection =
                    {
                            Carriers.NAME,
                            Carriers.APN,
                            Carriers.PORT,
                            Carriers.PROTOCOL,
                            Carriers.NUMERIC,
                    };
            String selection = Carriers.NAME + "=?";
            String[] selectionArgs = { NAME };
            Log.d(TAG, "testInsertCarriers query projection: " + Arrays.toString(testProjection)
                    + "\ntestInsertCarriers selection: " + selection
                    + "\ntestInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
            Cursor cursor = mContentResolver.query(
                    uri, testProjection, selection, selectionArgs, null);
            assertEquals("Unexpected number of APNs returned by cursor", 1, cursor.getCount());

            // try to delete with invalid selection
            String selectionToDelete = invalidColumn + "=?";
            String[] selectionArgsToDelete = { invalidColumn };
            Log.d(TAG, "testInsertCarriers deleting selection: " + selectionToDelete
                    + "testInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));

            try {
                mContentResolver.delete(uri, selectionToDelete, selectionArgsToDelete);
                fail();
            } catch (SQLiteException e) {
                // Expected: If there's no such a column, an exception will be thrown and the
                // Activity Manager will kill this process shortly.
            }

            // verify that deleted value is still there
            selection = Carriers.NAME + "=?";
            selectionArgs[0] = NAME;
            cursor = mContentResolver.query(uri, testProjection, selection, selectionArgs, null);
            assertEquals("Unexpected number of APNs returned by cursor", 1, cursor.getCount());

            // delete test content
            selectionToDelete = Carriers.NAME + "=?";
            selectionArgsToDelete[0] = NAME;
            Log.d(TAG, "testInsertCarriers deleting selection: " + selectionToDelete
                    + "testInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
            int numRowsDeleted = mContentResolver.delete(
                    uri, selectionToDelete, selectionArgsToDelete);
            assertEquals("Unexpected number of rows deleted", 1, numRowsDeleted);

            // verify that deleted values are gone
            cursor = mContentResolver.query(uri, testProjection, selection, selectionArgs, null);
            assertEquals("Unexpected number of rows deleted", 0, cursor.getCount());
        } catch (SecurityException e) {
            failMessage();
        }
    }

    private ContentValues makeDefaultContentValues() {
        ContentValues contentValues = new ContentValues();
        for (Map.Entry<String, String> entry: APN_MAP.entrySet()) {
            contentValues.put(entry.getKey(), entry.getValue());
        }
        return contentValues;
    }
}