/*
 * 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.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.UriMatcher;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.os.Environment;
import android.provider.Telephony.CarrierId;
import android.telephony.SubscriptionManager;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.SubscriptionController;
import com.android.internal.telephony.nano.CarrierIdProto;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import libcore.io.IoUtils;

/**
 * This class provides the ability to query the Carrier Identification databases
 * (A.K.A. cid) which is stored in a SQLite database.
 *
 * Each row in carrier identification db consists of matching rule (e.g., MCCMNC, GID1, GID2, PLMN)
 * and its matched carrier id & carrier name. Each carrier either MNO or MVNO could be
 * identified by multiple matching rules but is assigned with a unique ID (cid).
 *
 *
 * This class provides the ability to retrieve the cid of the current subscription.
 * This is done atomically through a query.
 *
 * This class also provides a way to update carrier identifying attributes of an existing entry.
 * Insert entries for new carriers or an existing carrier.
 */
public class CarrierIdProvider extends ContentProvider {

    private static final boolean VDBG = false; // STOPSHIP if true
    private static final String TAG = CarrierIdProvider.class.getSimpleName();

    private static final String DATABASE_NAME = "carrierIdentification.db";
    private static final int DATABASE_VERSION = 3;

    private static final String ASSETS_PB_FILE = "carrier_list.pb";
    private static final String VERSION_KEY = "version";
    private static final String OTA_UPDATED_PB_PATH = "misc/carrierid/" + ASSETS_PB_FILE;
    private static final String PREF_FILE = CarrierIdProvider.class.getSimpleName();

    private static final UriMatcher s_urlMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    private static final int URL_ALL                = 1;
    private static final int URL_ALL_UPDATE_FROM_PB = 2;
    private static final int URL_ALL_GET_VERSION    = 3;

    /**
     * index 0: {@link CarrierId.All#MCCMNC}
     */
    private static final int MCCMNC_INDEX                = 0;
    /**
     * index 1: {@link CarrierId.All#IMSI_PREFIX_XPATTERN}
     */
    private static final int IMSI_PREFIX_INDEX           = 1;
    /**
     * index 2: {@link CarrierId.All#GID1}
     */
    private static final int GID1_INDEX                  = 2;
    /**
     * index 3: {@link CarrierId.All#GID2}
     */
    private static final int GID2_INDEX                  = 3;
    /**
     * index 4: {@link CarrierId.All#PLMN}
     */
    private static final int PLMN_INDEX                  = 4;
    /**
     * index 5: {@link CarrierId.All#SPN}
     */
    private static final int SPN_INDEX                   = 5;
    /**
     * index 6: {@link CarrierId.All#APN}
     */
    private static final int APN_INDEX                   = 6;
    /**
    * index 7: {@link CarrierId.All#ICCID_PREFIX}
    */
    private static final int ICCID_PREFIX_INDEX          = 7;
    /**
     * ending index of carrier attribute list.
     */
    private static final int CARRIER_ATTR_END_IDX        = ICCID_PREFIX_INDEX;
    /**
     * The authority string for the CarrierIdProvider
     */
    @VisibleForTesting
    public static final String AUTHORITY = "carrier_id";

    public static final String CARRIER_ID_TABLE = "carrier_id";

    private static final List<String> CARRIERS_ID_UNIQUE_FIELDS = new ArrayList<>(Arrays.asList(
            CarrierId.All.MCCMNC,
            CarrierId.All.GID1,
            CarrierId.All.GID2,
            CarrierId.All.PLMN,
            CarrierId.All.IMSI_PREFIX_XPATTERN,
            CarrierId.All.SPN,
            CarrierId.All.APN,
            CarrierId.All.ICCID_PREFIX));

    private CarrierIdDatabaseHelper mDbHelper;

    /**
     * Stores carrier id information for the current active subscriptions.
     * Key is the active subId and entryValue is a pair of carrier id(int) and Carrier Name(String).
     */
    private final Map<Integer, Pair<Integer, String>> mCurrentSubscriptionMap =
            new ConcurrentHashMap<>();

    @VisibleForTesting
    public static String getStringForCarrierIdTableCreation(String tableName) {
        return "CREATE TABLE " + tableName
                + "(_id INTEGER PRIMARY KEY,"
                + CarrierId.All.MCCMNC + " TEXT NOT NULL,"
                + CarrierId.All.GID1 + " TEXT,"
                + CarrierId.All.GID2 + " TEXT,"
                + CarrierId.All.PLMN + " TEXT,"
                + CarrierId.All.IMSI_PREFIX_XPATTERN + " TEXT,"
                + CarrierId.All.SPN + " TEXT,"
                + CarrierId.All.APN + " TEXT,"
                + CarrierId.All.ICCID_PREFIX + " TEXT,"
                + CarrierId.CARRIER_NAME + " TEXT,"
                + CarrierId.CARRIER_ID + " INTEGER DEFAULT -1,"
                + "UNIQUE (" + TextUtils.join(", ", CARRIERS_ID_UNIQUE_FIELDS) + "));";
    }

    @VisibleForTesting
    public static String getStringForIndexCreation(String tableName) {
        return "CREATE INDEX IF NOT EXISTS mccmncIndex ON " + tableName + " ("
                + CarrierId.All.MCCMNC + ");";
    }

    @Override
    public boolean onCreate() {
        Log.d(TAG, "onCreate");
        mDbHelper = new CarrierIdDatabaseHelper(getContext());
        mDbHelper.getReadableDatabase();
        s_urlMatcher.addURI(AUTHORITY, "all", URL_ALL);
        s_urlMatcher.addURI(AUTHORITY, "all/update_db", URL_ALL_UPDATE_FROM_PB);
        s_urlMatcher.addURI(AUTHORITY, "all/get_version", URL_ALL_GET_VERSION);
        updateDatabaseFromPb(mDbHelper.getWritableDatabase());
        return true;
    }

    @Override
    public String getType(Uri uri) {
        Log.d(TAG, "getType");
        return null;
    }

    @Override
    public Cursor query(Uri uri, String[] projectionIn, String selection,
                        String[] selectionArgs, String sortOrder) {
        if (VDBG) {
            Log.d(TAG, "query:"
                    + " uri=" + uri
                    + " values=" + Arrays.toString(projectionIn)
                    + " selection=" + selection
                    + " selectionArgs=" + Arrays.toString(selectionArgs));
        }

        final int match = s_urlMatcher.match(uri);
        switch (match) {
            case URL_ALL_GET_VERSION:
                checkReadPermission();
                final MatrixCursor cursor = new MatrixCursor(new String[] {VERSION_KEY});
                cursor.addRow(new Object[] {getAppliedVersion()});
                return cursor;
            case URL_ALL:
                checkReadPermission();
                SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
                qb.setTables(CARRIER_ID_TABLE);

                SQLiteDatabase db = getReadableDatabase();
                return qb.query(db, projectionIn, selection, selectionArgs, null, null, sortOrder);
            default:
                return queryCarrierIdForCurrentSubscription(uri, projectionIn);
        }
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        checkWritePermission();
        final int match = s_urlMatcher.match(uri);
        switch (match) {
            case URL_ALL:
                final long row = getWritableDatabase().insertOrThrow(CARRIER_ID_TABLE, null,
                        values);
                if (row > 0) {
                    final Uri newUri = ContentUris.withAppendedId(
                            CarrierId.All.CONTENT_URI, row);
                    getContext().getContentResolver().notifyChange(
                            CarrierId.All.CONTENT_URI, null);
                    return newUri;
                }
                return null;
            default:
                throw new IllegalArgumentException("Cannot insert that URL: " + uri);
        }
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        checkWritePermission();
        if (VDBG) {
            Log.d(TAG, "delete:"
                    + " uri=" + uri
                    + " selection={" + selection + "}"
                    + " selection=" + selection
                    + " selectionArgs=" + Arrays.toString(selectionArgs));
        }
        final int match = s_urlMatcher.match(uri);
        switch (match) {
            case URL_ALL:
                final int count = getWritableDatabase().delete(CARRIER_ID_TABLE, selection,
                        selectionArgs);
                Log.d(TAG, "  delete.count=" + count);
                if (count > 0) {
                    getContext().getContentResolver().notifyChange(
                            CarrierId.All.CONTENT_URI, null);
                }
                return count;
            default:
                throw new IllegalArgumentException("Cannot delete that URL: " + uri);
        }
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        checkWritePermission();
        if (VDBG) {
            Log.d(TAG, "update:"
                    + " uri=" + uri
                    + " values={" + values + "}"
                    + " selection=" + selection
                    + " selectionArgs=" + Arrays.toString(selectionArgs));
        }

        final int match = s_urlMatcher.match(uri);
        switch (match) {
            case URL_ALL_UPDATE_FROM_PB:
                return updateDatabaseFromPb(getWritableDatabase());
            case URL_ALL:
                final int count = getWritableDatabase().update(CARRIER_ID_TABLE, values, selection,
                        selectionArgs);
                Log.d(TAG, "  update.count=" + count);
                if (count > 0) {
                    getContext().getContentResolver().notifyChange(CarrierId.All.CONTENT_URI, null);
                }
                return count;
            default:
                return updateCarrierIdForCurrentSubscription(uri, values);

        }
    }

    /**
     * These methods can be overridden in a subclass for testing CarrierIdProvider using an
     * in-memory database.
     */
    SQLiteDatabase getReadableDatabase() {
        return mDbHelper.getReadableDatabase();
    }
    SQLiteDatabase getWritableDatabase() {
        return mDbHelper.getWritableDatabase();
    }

    private class CarrierIdDatabaseHelper extends SQLiteOpenHelper {
        private final String TAG = CarrierIdDatabaseHelper.class.getSimpleName();

        /**
         * CarrierIdDatabaseHelper carrier identification database helper class.
         * @param context of the user.
         */
        public CarrierIdDatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            Log.d(TAG, "onCreate");
            db.execSQL(getStringForCarrierIdTableCreation(CARRIER_ID_TABLE));
            db.execSQL(getStringForIndexCreation(CARRIER_ID_TABLE));
        }

        public void createCarrierTable(SQLiteDatabase db) {
            db.execSQL(getStringForCarrierIdTableCreation(CARRIER_ID_TABLE));
            db.execSQL(getStringForIndexCreation(CARRIER_ID_TABLE));
        }

        public void dropCarrierTable(SQLiteDatabase db) {
            db.execSQL("DROP TABLE IF EXISTS " + CARRIER_ID_TABLE + ";");
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.d(TAG, "dbh.onUpgrade:+ db=" + db + " oldV=" + oldVersion + " newV=" + newVersion);
            if (oldVersion < DATABASE_VERSION) {
                dropCarrierTable(db);
                createCarrierTable(db);
            }
        }
    }

    /**
     * Parse and persist pb file as database default values.
     * Use version number to detect file update.
     * Update database with data from assets or ota only if version jumps.
     */
    private int updateDatabaseFromPb(SQLiteDatabase db) {
        Log.d(TAG, "update database from pb file");
        int rows = 0;
        CarrierIdProto.CarrierList carrierList = getUpdateCarrierList();
        // No update is needed
        if (carrierList == null) return rows;

        ContentValues cv;
        List<ContentValues> cvs;
        try {
            // Batch all insertions in a single transaction to improve efficiency.
            db.beginTransaction();
            db.delete(CARRIER_ID_TABLE, null, null);
            for (CarrierIdProto.CarrierId id : carrierList.carrierId) {
                for (CarrierIdProto.CarrierAttribute attr : id.carrierAttribute) {
                    cv = new ContentValues();
                    cv.put(CarrierId.CARRIER_ID, id.canonicalId);
                    cv.put(CarrierId.CARRIER_NAME, id.carrierName);
                    cvs = new ArrayList<>();
                    convertCarrierAttrToContentValues(cv, cvs, attr, 0);
                    for (ContentValues contentVal : cvs) {
                        // When a constraint violation occurs, the row that contains the violation
                        // is not inserted. But the command continues executing normally.
                        if (db.insertWithOnConflict(CARRIER_ID_TABLE, null, contentVal,
                                SQLiteDatabase.CONFLICT_IGNORE) > 0) {
                            rows++;
                        } else {
                            Log.e(TAG, "updateDatabaseFromPB insertion failure, row: "
                                    + rows + "carrier id: " + id.canonicalId);
                            // TODO metrics
                        }
                    }
                }
            }
            Log.d(TAG, "update database from pb. inserted rows = " + rows);
            if (rows > 0) {
                // Notify listener of DB change
                getContext().getContentResolver().notifyChange(CarrierId.All.CONTENT_URI, null);
            }
            setAppliedVersion(carrierList.version);
            db.setTransactionSuccessful();
        } finally {
            db.endTransaction();
        }
        return rows;
    }

    /**
     * Recursively loop through carrier attribute list to get all combinations.
     */
    private void convertCarrierAttrToContentValues(ContentValues cv, List<ContentValues> cvs,
            CarrierIdProto.CarrierAttribute attr, int index) {
        if (index > CARRIER_ATTR_END_IDX) {
            cvs.add(new ContentValues(cv));
            return;
        }
        boolean found = false;
        switch (index) {
            case MCCMNC_INDEX:
                for (String str : attr.mccmncTuple) {
                    cv.put(CarrierId.All.MCCMNC, str);
                    convertCarrierAttrToContentValues(cv, cvs, attr, index + 1);
                    cv.remove(CarrierId.All.MCCMNC);
                    found = true;
                }
                break;
            case IMSI_PREFIX_INDEX:
                for (String str : attr.imsiPrefixXpattern) {
                    cv.put(CarrierId.All.IMSI_PREFIX_XPATTERN, str);
                    convertCarrierAttrToContentValues(cv, cvs, attr, index + 1);
                    cv.remove(CarrierId.All.IMSI_PREFIX_XPATTERN);
                    found = true;
                }
                break;
            case GID1_INDEX:
                for (String str : attr.gid1) {
                    cv.put(CarrierId.All.GID1, str);
                    convertCarrierAttrToContentValues(cv, cvs, attr, index + 1);
                    cv.remove(CarrierId.All.GID1);
                    found = true;
                }
                break;
            case GID2_INDEX:
                for (String str : attr.gid2) {
                    cv.put(CarrierId.All.GID2, str);
                    convertCarrierAttrToContentValues(cv, cvs, attr, index + 1);
                    cv.remove(CarrierId.All.GID2);
                    found = true;
                }
                break;
            case PLMN_INDEX:
                for (String str : attr.plmn) {
                    cv.put(CarrierId.All.PLMN, str);
                    convertCarrierAttrToContentValues(cv, cvs, attr, index + 1);
                    cv.remove(CarrierId.All.PLMN);
                    found = true;
                }
                break;
            case SPN_INDEX:
                for (String str : attr.spn) {
                    cv.put(CarrierId.All.SPN, str);
                    convertCarrierAttrToContentValues(cv, cvs, attr, index + 1);
                    cv.remove(CarrierId.All.SPN);
                    found = true;
                }
                break;
            case APN_INDEX:
                for (String str : attr.preferredApn) {
                    cv.put(CarrierId.All.APN, str);
                    convertCarrierAttrToContentValues(cv, cvs, attr, index + 1);
                    cv.remove(CarrierId.All.APN);
                    found = true;
                }
                break;
            case ICCID_PREFIX_INDEX:
                for (String str : attr.iccidPrefix) {
                    cv.put(CarrierId.All.ICCID_PREFIX, str);
                    convertCarrierAttrToContentValues(cv, cvs, attr, index + 1);
                    cv.remove(CarrierId.All.ICCID_PREFIX);
                    found = true;
                }
                break;
            default:
                Log.e(TAG, "unsupported index: " + index);
                break;
        }
        // if attribute at index is empty, move forward to the next attribute
        if (!found) {
            convertCarrierAttrToContentValues(cv, cvs, attr, index + 1);
        }
    }

    /**
     * Return the update carrierList.
     * Get the latest version from the last applied, assets and ota file. if the latest version
     * is newer than the last applied, update is required. Otherwise no update is required and
     * the returned carrierList will be null.
     */
    private CarrierIdProto.CarrierList getUpdateCarrierList() {
        int version = getAppliedVersion();
        CarrierIdProto.CarrierList carrierList = null;
        CarrierIdProto.CarrierList assets = null;
        CarrierIdProto.CarrierList ota = null;
        InputStream is = null;

        try {
            is = getContext().getAssets().open(ASSETS_PB_FILE);
            assets = CarrierIdProto.CarrierList.parseFrom(readInputStreamToByteArray(is));
        } catch (IOException ex) {
            Log.e(TAG, "read carrier list from assets pb failure: " + ex);
        } finally {
            IoUtils.closeQuietly(is);
        }
        try {
            is = new FileInputStream(new File(Environment.getDataDirectory(), OTA_UPDATED_PB_PATH));
            ota = CarrierIdProto.CarrierList.parseFrom(readInputStreamToByteArray(is));
        } catch (IOException ex) {
            Log.e(TAG, "read carrier list from ota pb failure: " + ex);
        } finally {
            IoUtils.closeQuietly(is);
        }

        // compare version
        if (assets != null && assets.version > version) {
            carrierList = assets;
            version = assets.version;
        }
        if (ota != null && ota.version > version) {
            carrierList = ota;
            version = ota.version;
        }
        Log.d(TAG, "latest version: " + version + " need update: " + (carrierList != null));
        return carrierList;
    }

    private int getAppliedVersion() {
        final SharedPreferences sp = getContext().getSharedPreferences(PREF_FILE,
                Context.MODE_PRIVATE);
        return sp.getInt(VERSION_KEY, -1);
    }

    private void setAppliedVersion(int version) {
        final SharedPreferences sp = getContext().getSharedPreferences(PREF_FILE,
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putInt(VERSION_KEY, version);
        editor.apply();
    }

    /**
     * Util function to convert inputStream to byte array before parsing proto data.
     */
    private static byte[] readInputStreamToByteArray(InputStream inputStream) throws IOException {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        int nRead;
        int size = 16 * 1024; // Read 16k chunks
        byte[] data = new byte[size];
        while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, nRead);
        }
        buffer.flush();
        return buffer.toByteArray();
    }

    private int updateCarrierIdForCurrentSubscription(Uri uri, ContentValues cv) {
        // Parse the subId
        int subId;
        try {
            subId = Integer.parseInt(uri.getLastPathSegment());
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("invalid subid in provided uri " + uri);
        }
        Log.d(TAG, "updateCarrierIdForSubId: " + subId);

        // Handle DEFAULT_SUBSCRIPTION_ID
        if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
            subId = SubscriptionController.getInstance().getDefaultSubId();
        }

        if (!SubscriptionController.getInstance().isActiveSubId(subId)) {
            // Remove absent subId from the currentSubscriptionMap.
            final List activeSubscriptions = Arrays.asList(SubscriptionController.getInstance()
                    .getActiveSubIdList());
            int count = 0;
            for (int subscription : mCurrentSubscriptionMap.keySet()) {
                if (!activeSubscriptions.contains(subscription)) {
                    count++;
                    Log.d(TAG, "updateCarrierIdForSubId: " + subscription);
                    mCurrentSubscriptionMap.remove(subscription);
                    getContext().getContentResolver().notifyChange(CarrierId.CONTENT_URI, null);
                }
            }
            return count;
        } else {
            mCurrentSubscriptionMap.put(subId,
                    new Pair(cv.getAsInteger(CarrierId.CARRIER_ID),
                    cv.getAsString(CarrierId.CARRIER_NAME)));
            getContext().getContentResolver().notifyChange(CarrierId.CONTENT_URI, null);
            return 1;
        }
    }

    private Cursor queryCarrierIdForCurrentSubscription(Uri uri, String[] projectionIn) {
        // Parse the subId, using the default subId if subId is not provided
        int subId = SubscriptionController.getInstance().getDefaultSubId();
        if (!TextUtils.isEmpty(uri.getLastPathSegment())) {
            try {
                subId = Integer.parseInt(uri.getLastPathSegment());
            } catch (NumberFormatException e) {
                throw new IllegalArgumentException("invalid subid in provided uri" + uri);
            }
        }
        Log.d(TAG, "queryCarrierIdForSubId: " + subId);

        // Handle DEFAULT_SUBSCRIPTION_ID
        if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
            subId = SubscriptionController.getInstance().getDefaultSubId();
        }

        if (!mCurrentSubscriptionMap.containsKey(subId)) {
            // Return an empty cursor if subId is not belonging to current subscriptions.
            return new MatrixCursor(projectionIn, 0);
        }
        final MatrixCursor c = new MatrixCursor(projectionIn, 1);
        final MatrixCursor.RowBuilder row = c.newRow();
        for (int i = 0; i < c.getColumnCount(); i++) {
            final String columnName = c.getColumnName(i);
            if (CarrierId.CARRIER_ID.equals(columnName)) {
                row.add(mCurrentSubscriptionMap.get(subId).first);
            } else if (CarrierId.CARRIER_NAME.equals(columnName)) {
                row.add(mCurrentSubscriptionMap.get(subId).second);
            } else {
                throw new IllegalArgumentException("Invalid column " + projectionIn[i]);
            }
        }
        return c;
    }

    private void checkReadPermission() {
        int status = getContext().checkCallingOrSelfPermission(
                "android.permission.READ_PRIVILEGED_PHONE_STATE");
        if (status == PackageManager.PERMISSION_GRANTED) {
            return;
        }
        throw new SecurityException("No permission to read CarrierId provider");
    }

    private void checkWritePermission() {
        int status = getContext().checkCallingOrSelfPermission(
                "android.permission.MODIFY_PHONE_STATE");
        if (status == PackageManager.PERMISSION_GRANTED) {
            return;
        }
        throw new SecurityException("No permission to write CarrierId provider");
    }
}
