/*
 * Copyright (c) 2015, Motorola Mobility LLC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     - Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     - Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     - Neither the name of Motorola Mobility nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 */

package com.android.service.ims.presence;

import java.io.FileNotFoundException;

import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.provider.BaseColumns;
import android.provider.ContactsContract.Contacts;
import android.content.ComponentName;

import com.android.ims.RcsPresenceInfo;
import com.android.ims.internal.EABContract;
import com.android.ims.internal.Logger;

/**
 * @author Vishal Patil (A22809)
 */

public class EABProvider extends DatabaseContentProvider{
    private Logger logger = Logger.getLogger(this.getClass().getName());

    private static final String EAB_DB_NAME = "rcseab.db";

    private static final int EAB_DB_VERSION = 2;

    private static final int EAB_TABLE = 1;

    private static final int EAB_TABLE_ID = 2;

    private static final int EAB_GROUPITEMS_TABLE = 3;

    private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH) {
        {
            addURI(EABContract.AUTHORITY, EABContract.EABColumns.TABLE_NAME, EAB_TABLE);
            addURI(EABContract.AUTHORITY, EABContract.EABColumns.TABLE_NAME + "/#", EAB_TABLE_ID);
            addURI(EABContract.AUTHORITY, EABContract.EABColumns.GROUPITEMS_NAME,
                    EAB_GROUPITEMS_TABLE);
        }
    };

    /* Statement to create VMM Album table. */
    private static final String EAB_CREATE_STATEMENT = "create table if not exists "
            + EABContract.EABColumns.TABLE_NAME
            + "("
            + EABContract.EABColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
            + EABContract.EABColumns.CONTACT_NAME + " TEXT, "
            + EABContract.EABColumns.CONTACT_NUMBER + " TEXT, "
            + EABContract.EABColumns.RAW_CONTACT_ID + " TEXT, "
            + EABContract.EABColumns.CONTACT_ID + " TEXT, "
            + EABContract.EABColumns.DATA_ID + " TEXT, "
            + EABContract.EABColumns.ACCOUNT_TYPE  + " TEXT, "
            + EABContract.EABColumns.VOLTE_CALL_SERVICE_CONTACT_ADDRESS + " TEXT, "
            + EABContract.EABColumns.VOLTE_CALL_CAPABILITY + " INTEGER, "
            + EABContract.EABColumns.VOLTE_CALL_CAPABILITY_TIMESTAMP + " LONG, "
            + EABContract.EABColumns.VOLTE_CALL_AVAILABILITY + " INTEGER, "
            + EABContract.EABColumns.VOLTE_CALL_AVAILABILITY_TIMESTAMP + " LONG, "
            + EABContract.EABColumns.VIDEO_CALL_SERVICE_CONTACT_ADDRESS + " TEXT, "
            + EABContract.EABColumns.VIDEO_CALL_CAPABILITY + " INTEGER, "
            + EABContract.EABColumns.VIDEO_CALL_CAPABILITY_TIMESTAMP + " LONG, "
            + EABContract.EABColumns.VIDEO_CALL_AVAILABILITY + " INTEGER, "
            + EABContract.EABColumns.VIDEO_CALL_AVAILABILITY_TIMESTAMP + " LONG, "
            + EABContract.EABColumns.CONTACT_LAST_UPDATED_TIMESTAMP + " LONG "
            + ");";

    private static final String EAB_DROP_STATEMENT = "drop table if exists "
            + EABContract.EABColumns.TABLE_NAME + ";";

    public EABProvider() {
        super(EAB_DB_NAME, EAB_DB_VERSION);
    }

    @Override
    public void bootstrapDatabase(SQLiteDatabase db) {
        logger.info("Enter: bootstrapDatabase() Creating new EAB database");
        upgradeDatabase(db, 0, EAB_DB_VERSION);
        logger.info("Exit: bootstrapDatabase()");
    }

    /*
     * In upgradeDatabase,
     * oldVersion - the current version of Provider on the phone.
     * newVersion - the version of Provider where the phone will be upgraded to.
     */
    @Override
    public boolean upgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion) {
        logger.debug("Enter: upgradeDatabase() - oldVersion = " + oldVersion +
                " newVersion = " + newVersion);

        if (oldVersion == newVersion) {
            logger.debug("upgradeDatabase oldVersion == newVersion, No Upgrade Required");
            return true;
        }

        try {
            if (oldVersion == 0) {
                db.execSQL(EAB_CREATE_STATEMENT);

                oldVersion++;
                logger.debug("upgradeDatabase : DB has been upgraded to " + oldVersion);
            }
            if (oldVersion == 1) {
                addColumn(db, EABContract.EABColumns.TABLE_NAME,
                        EABContract.EABColumns.VOLTE_STATUS, "INTEGER NOT NULL DEFAULT -1");

                oldVersion++;
                logger.debug("upgradeDatabase : DB has been upgraded to " + oldVersion);
            }
        } catch (SQLException exception) {
            logger.error("Exception during upgradeDatabase. " + exception.getMessage());
            // DB file had problem
            throw new InvalidDBException();
        }

        // add further upgrade code above this
        if (oldVersion == newVersion) {
            logger.debug("DB upgrade complete : to " + newVersion);
        }

        logger.debug("Exit: upgradeDatabase()");
        return true;
    }

    @Override
    protected boolean downgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion) {
        // throwing the custom created Exception to catch it in
        // getWritableDatabase or getReadableDatabase
        throw new InvalidDBException();
    }

    @Override
    protected int deleteInternal(SQLiteDatabase db, Uri uri, String selection,
            String[] selectionArgs) {
        logger.info("Enter: deleteInternal()");
        final int match = URI_MATCHER.match(uri);
        String table = null;
        switch (match) {
            case EAB_TABLE_ID:
                if (selection == null) {
                    selection = "_id=?";
                    selectionArgs = new String[] {uri.getPathSegments().get(1)};
                }
            case EAB_TABLE:
                table = EABContract.EABColumns.TABLE_NAME;
                break;
            default:
                logger.info("No match for " + uri);
                logger.info("Exit: deleteInternal()");
                return 0;
        }
        logger.debug("Deleting from the table" + table + " selection= " + selection);
        printDeletingValues(uri, selection, selectionArgs);
        logger.info("Exit: deleteInternal()");
        return db.delete(table, selection, selectionArgs);
    }

    @Override
    protected Uri insertInternal(SQLiteDatabase db, Uri uri, ContentValues values) {
        logger.info("Enter: insertInternal()");
        final int match = URI_MATCHER.match(uri);
        String table = null;
        String nullColumnHack = null;
        switch (match) {
            case EAB_TABLE:
                table = EABContract.EABColumns.TABLE_NAME;
                break;
            default:
                logger.warn("No match for " + uri);
                logger.info("Exit: insertInternal() with null");
                return null;
        }
        values = verifyIfMdnExists(values);
        // Do the insert.
        logger.debug("Inserting to the table" + table + " values=" + values.toString());

        final long id = db.insert(table, nullColumnHack, values);
        if (id > 0) {
            String contactNumber = values.getAsString(EABContract.EABColumns.CONTACT_NUMBER);
            sendInsertBroadcast(contactNumber);
            logger.info("Exit: insertInternal()");
            return ContentUris.withAppendedId(uri, id);
        } else {
            logger.info("Exit: insertInternal() with null");
            return null;
        }
    }

    @Override
    protected Cursor queryInternal(SQLiteDatabase db, Uri uri, String[] projection,
            String selection, String[] selectionArgs, String sortOrder) {
        logger.info("Enter: queryInternal()");
        final int match = URI_MATCHER.match(uri);

        switch (match) {
            case EAB_TABLE_ID:
                long id = ContentUris.parseId(uri);
                logger.debug("queryInternal id=" + id);
                String idSelection = BaseColumns._ID + "=" + id;
                if(null != selection) {
                    selection = "((" + idSelection + ") AND (" + selection + "))";
                } else {
                    selection = idSelection;
                }
                break;
            case EAB_GROUPITEMS_TABLE:
                SQLiteQueryBuilder sqb = new SQLiteQueryBuilder();
                sqb.setTables(EABContract.EABColumns.TABLE_NAME);
                String rawquery = "select DISTINCT " + EABContract.EABColumns.CONTACT_ID
                        + " from " + EABContract.EABColumns.TABLE_NAME
                        + " where " + EABContract.EABColumns.VOLTE_CALL_CAPABILITY + " >'" +
                        RcsPresenceInfo.ServiceState.OFFLINE+"' AND "
                        + EABContract.EABColumns.VIDEO_CALL_CAPABILITY + " >'"
                        + RcsPresenceInfo.ServiceState.OFFLINE + "'";
                StringBuffer sb = new StringBuffer();
                Cursor cursor = db.rawQuery(rawquery, null);
                if (cursor != null && cursor.moveToFirst()) {
                    do {
                        if (sb.length() != 0) sb.append(",");
                        String contactId = cursor.getString(cursor
                                .getColumnIndex(EABContract.EABColumns.CONTACT_ID));
                        sb.append(contactId);
                    } while (cursor.moveToNext());
                }
                if (cursor != null) cursor.close();
                String contactSel = Contacts._ID + " IN ( " + sb.toString() + ")";
                return getContext().getContentResolver().query(Contacts.CONTENT_URI, projection,
                                contactSel, null, sortOrder);
        }

        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

        String groupBy = uri.getQueryParameter("groupby");
        String having = null;

        switch (match) {
            case EAB_TABLE:
            case EAB_TABLE_ID:
                qb.setTables(EABContract.EABColumns.TABLE_NAME);
                break;
            default:
                logger.warn("No match for " + uri);
                logger.info("Exit: queryInternal()");
                return null;
        }
        logger.info("Exit: queryInternal()");
        return qb.query(db, projection, selection, selectionArgs, groupBy, having, sortOrder);
    }

    @Override
    protected int updateInternal(SQLiteDatabase db, Uri uri, ContentValues values,
            String selection, String[] selectionArgs) {
        logger.info("Enter: updateInternal()");
        int result = 0;
        final int match = URI_MATCHER.match(uri);

        switch (match) {
            case EAB_TABLE_ID:
                long id = ContentUris.parseId(uri);
                logger.debug("updateInternal id=" + id);
                String idSelection = BaseColumns._ID + "=" + id;
                if(null != selection){
                    selection = "((" + idSelection + ") AND (" + selection + "))";
                } else {
                    selection = idSelection;
                }
                break;
        }

        String table = null;
        switch (match) {
            case EAB_TABLE:
            case EAB_TABLE_ID:
                table = EABContract.EABColumns.TABLE_NAME;
                break;
            default:
                logger.warn("No match for " + uri);
                break;
        }

        if (table != null && values != null) {
            logger.debug("Updating the table " + table + " values= " + values.toString());
            result = db.update(table, values, selection, selectionArgs);
        }
        logger.info("Exit: updateInternal()");
        return result;
    }

    @Override
    public String getType(Uri uri) {
        logger.info("Enter: getType()");
        final int match = URI_MATCHER.match(uri);
        switch (match) {
            case EAB_TABLE:
                return EABContract.EABColumns.CONTENT_TYPE;
            case EAB_TABLE_ID:
                return EABContract.EABColumns.CONTENT_ITEM_TYPE;
            default:
                throw (new IllegalArgumentException("EABProvider URI: " + uri));
        }
    }

    @Override
    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
        return null;
    }

    private void sendInsertBroadcast(String contactNumber) {
        Intent intent = new Intent(com.android.service.ims.presence.Contacts
            .ACTION_NEW_CONTACT_INSERTED);
        ComponentName component = new ComponentName("com.android.service.ims.presence",
                "com.android.service.ims.presence.AlarmBroadcastReceiver");
        intent.setComponent(component);

        intent.putExtra(com.android.service.ims.presence.Contacts.NEW_PHONE_NUMBER, contactNumber);
        getContext().sendBroadcast(intent);
    }

    private ContentValues verifyIfMdnExists(ContentValues cvalues) {
        String phoneNumber = null;
        if (cvalues.containsKey(EABContract.EABColumns.CONTACT_NUMBER)) {
            phoneNumber = cvalues.getAsString(EABContract.EABColumns.CONTACT_NUMBER);
        } else {
            return cvalues;
        }
        if (null == phoneNumber) {
            return cvalues;
        }
        String[] projection = new String[] {
                EABContract.EABColumns.VOLTE_CALL_SERVICE_CONTACT_ADDRESS,
                EABContract.EABColumns.VOLTE_CALL_CAPABILITY,
                EABContract.EABColumns.VOLTE_CALL_CAPABILITY_TIMESTAMP,
                EABContract.EABColumns.VOLTE_CALL_AVAILABILITY,
                EABContract.EABColumns.VOLTE_CALL_AVAILABILITY_TIMESTAMP,
                EABContract.EABColumns.VIDEO_CALL_SERVICE_CONTACT_ADDRESS,
                EABContract.EABColumns.VIDEO_CALL_CAPABILITY,
                EABContract.EABColumns.VIDEO_CALL_CAPABILITY_TIMESTAMP,
                EABContract.EABColumns.VIDEO_CALL_AVAILABILITY,
                EABContract.EABColumns.VIDEO_CALL_AVAILABILITY_TIMESTAMP};
        String whereClause = "PHONE_NUMBERS_EQUAL(" +
                EABContract.EABColumns.CONTACT_NUMBER + ", ?, 0)";
        String[] selectionArgs = new String[] { phoneNumber };
        Cursor cursor = getContext().getContentResolver().query(EABContract.EABColumns.CONTENT_URI,
                        projection, whereClause, selectionArgs, null);
        if ((null != cursor) && (cursor.getCount() > 0)) {
            logger.debug("Number : " + phoneNumber +
                    " is already stored in EAB DB - cursor count is " + cursor.getCount());
            logger.error("Inserting another copy of MDN to EAB DB.");
            // Update data only from first cursor element.
            cursor.moveToNext();
            cvalues.put(EABContract.EABColumns.VOLTE_CALL_SERVICE_CONTACT_ADDRESS,
                    cursor.getString(cursor.
                    getColumnIndex(EABContract.EABColumns.VOLTE_CALL_SERVICE_CONTACT_ADDRESS)));
            cvalues.put(EABContract.EABColumns.VOLTE_CALL_CAPABILITY, cursor.getString(cursor
                    .getColumnIndex(EABContract.EABColumns.VOLTE_CALL_CAPABILITY)));
            cvalues.put(EABContract.EABColumns.VOLTE_CALL_CAPABILITY_TIMESTAMP,
                    cursor.getLong(cursor
                    .getColumnIndex(EABContract.EABColumns.VOLTE_CALL_CAPABILITY_TIMESTAMP)));
            cvalues.put(EABContract.EABColumns.VOLTE_CALL_AVAILABILITY, cursor.getString(cursor
                    .getColumnIndex(EABContract.EABColumns.VOLTE_CALL_AVAILABILITY)));
            cvalues.put(EABContract.EABColumns.VOLTE_CALL_AVAILABILITY_TIMESTAMP,
                    cursor.getLong(cursor
                    .getColumnIndex(EABContract.EABColumns.VOLTE_CALL_AVAILABILITY_TIMESTAMP)));
            cvalues.put(EABContract.EABColumns.VIDEO_CALL_SERVICE_CONTACT_ADDRESS,
                    cursor.getString(cursor
                    .getColumnIndex(EABContract.EABColumns.VIDEO_CALL_SERVICE_CONTACT_ADDRESS)));
            cvalues.put(EABContract.EABColumns.VIDEO_CALL_CAPABILITY, cursor.getString(cursor
                    .getColumnIndex(EABContract.EABColumns.VIDEO_CALL_CAPABILITY)));
            cvalues.put(EABContract.EABColumns.VIDEO_CALL_CAPABILITY_TIMESTAMP,
                    cursor.getLong(cursor
                    .getColumnIndex(EABContract.EABColumns.VIDEO_CALL_CAPABILITY_TIMESTAMP)));
            cvalues.put(EABContract.EABColumns.VIDEO_CALL_AVAILABILITY, cursor.getString(cursor
                    .getColumnIndex(EABContract.EABColumns.VIDEO_CALL_AVAILABILITY)));
            cvalues.put(EABContract.EABColumns.VIDEO_CALL_AVAILABILITY_TIMESTAMP,
                    cursor.getLong(cursor
                    .getColumnIndex(EABContract.EABColumns.VIDEO_CALL_AVAILABILITY_TIMESTAMP)));
            cvalues.put(EABContract.EABColumns.CONTACT_LAST_UPDATED_TIMESTAMP, 0);
        }
        if (null != cursor) {
            cursor.close();
        }
        return cvalues;
    }

    private void printDeletingValues(Uri uri, String selection, String[] selectionArgs) {
        String[] projection = new String[] {
                EABContract.EABColumns.CONTACT_NUMBER,
                EABContract.EABColumns.CONTACT_NAME,
                EABContract.EABColumns.RAW_CONTACT_ID,
                EABContract.EABColumns.CONTACT_ID,
                EABContract.EABColumns.DATA_ID};
        Cursor cursor = getContext().getContentResolver().query(EABContract.EABColumns.CONTENT_URI,
                        projection, selection, selectionArgs, null);
        if ((null != cursor) && (cursor.getCount() > 0)) {
            logger.debug("Before deleting the cursor count is " + cursor.getCount());
            // Update data only from first cursor element.
            while (cursor.moveToNext()) {
                long dataId = cursor.getLong(cursor.getColumnIndex(
                        EABContract.EABColumns.DATA_ID));
                long contactId = cursor.getLong(cursor.getColumnIndex(
                        EABContract.EABColumns.CONTACT_ID));
                long rawContactId = cursor.getLong(cursor.getColumnIndex(
                        EABContract.EABColumns.RAW_CONTACT_ID));
                String phoneNumber = cursor.getString(cursor.getColumnIndex(
                        EABContract.EABColumns.CONTACT_NUMBER));
                String displayName = cursor.getString(cursor.getColumnIndex(
                        EABContract.EABColumns.CONTACT_NAME));
                logger.debug("Deleting : dataId : " + dataId + " contactId :"  + contactId +
                        " rawContactId :" + rawContactId + " phoneNumber :" + phoneNumber +
                        " displayName :" + displayName);
            }
        } else {
            logger.error("cursor is null!");
        }
        if (null != cursor) {
            cursor.close();
        }
    }
}
