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

import android.annotation.Nullable;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.mtp.MtpObjectInfo;
import android.provider.DocumentsContract.Document;
import android.provider.DocumentsContract.Root;
import android.util.ArraySet;
import android.util.Log;

import com.android.internal.util.Preconditions;

import java.io.FileNotFoundException;
import java.util.Set;

import static com.android.mtp.MtpDatabaseConstants.*;
import static com.android.mtp.MtpDatabase.strings;

/**
 * Mapping operations for MtpDatabase.
 * Also see the comments of {@link MtpDatabase}.
 */
class Mapper {
    private static final String[] EMPTY_ARGS = new String[0];
    private final MtpDatabase mDatabase;

    /**
     * IDs which currently Mapper operates mapping for.
     */
    private final Set<String> mInMappingIds = new ArraySet<>();

    Mapper(MtpDatabase database) {
        mDatabase = database;
    }

    /**
     * Puts device information to database.
     *
     * @return If device is added to the database.
     * @throws FileNotFoundException
     */
    synchronized boolean putDeviceDocument(MtpDeviceRecord device) throws FileNotFoundException {
        final SQLiteDatabase database = mDatabase.getSQLiteDatabase();
        database.beginTransaction();
        try {
            final ContentValues[] valuesList = new ContentValues[1];
            final ContentValues[] extraValuesList = new ContentValues[1];
            valuesList[0] = new ContentValues();
            extraValuesList[0] = new ContentValues();
            MtpDatabase.getDeviceDocumentValues(valuesList[0], extraValuesList[0], device);
            final boolean changed = putDocuments(
                    null,
                    valuesList,
                    extraValuesList,
                    COLUMN_PARENT_DOCUMENT_ID + " IS NULL",
                    EMPTY_ARGS,
                    strings(COLUMN_DEVICE_ID, COLUMN_MAPPING_KEY));
            database.setTransactionSuccessful();
            return changed;
        } finally {
            database.endTransaction();
        }
    }

    /**
     * Puts root information to database.
     *
     * @param parentDocumentId Document ID of device document.
     * @param roots List of root information.
     * @return If roots are added or removed from the database.
     * @throws FileNotFoundException
     */
    synchronized boolean putStorageDocuments(
            String parentDocumentId, int[] operationsSupported, MtpRoot[] roots)
            throws FileNotFoundException {
        final SQLiteDatabase database = mDatabase.getSQLiteDatabase();
        database.beginTransaction();
        try {
            final ContentValues[] valuesList = new ContentValues[roots.length];
            final ContentValues[] extraValuesList = new ContentValues[roots.length];
            for (int i = 0; i < roots.length; i++) {
                valuesList[i] = new ContentValues();
                extraValuesList[i] = new ContentValues();
                MtpDatabase.getStorageDocumentValues(
                        valuesList[i],
                        extraValuesList[i],
                        parentDocumentId,
                        operationsSupported,
                        roots[i]);
            }
            final boolean changed = putDocuments(
                    parentDocumentId,
                    valuesList,
                    extraValuesList,
                    COLUMN_PARENT_DOCUMENT_ID + " = ?",
                    strings(parentDocumentId),
                    strings(COLUMN_STORAGE_ID, Document.COLUMN_DISPLAY_NAME));

            database.setTransactionSuccessful();
            return changed;
        } finally {
            database.endTransaction();
        }
    }

    /**
     * Puts document information to database.
     *
     * @param deviceId Device ID
     * @param parentId Parent document ID.
     * @param documents List of document information.
     * @throws FileNotFoundException
     */
    synchronized void putChildDocuments(
            int deviceId, String parentId, int[] operationsSupported, MtpObjectInfo[] documents)
            throws FileNotFoundException {
        final ContentValues[] valuesList = new ContentValues[documents.length];
        for (int i = 0; i < documents.length; i++) {
            valuesList[i] = new ContentValues();
            MtpDatabase.getObjectDocumentValues(
                    valuesList[i], deviceId, parentId, operationsSupported, documents[i]);
        }
        putDocuments(
                parentId,
                valuesList,
                null,
                COLUMN_PARENT_DOCUMENT_ID + " = ?",
                strings(parentId),
                strings(COLUMN_OBJECT_HANDLE, Document.COLUMN_DISPLAY_NAME));
    }

    void clearMapping() {
        final SQLiteDatabase database = mDatabase.getSQLiteDatabase();
        database.beginTransaction();
        try {
            mInMappingIds.clear();
            // Disconnect all device rows.
            try {
                startAddingDocuments(null);
                stopAddingDocuments(null);
            } catch (FileNotFoundException exception) {
                Log.e(MtpDocumentsProvider.TAG, "Unexpected FileNotFoundException.", exception);
                throw new RuntimeException(exception);
            }
            database.setTransactionSuccessful();
        } finally {
            database.endTransaction();
        }
    }

    /**
     * Starts adding new documents.
     * It changes the direct child documents of the given document from VALID to INVALIDATED.
     * Note that it keeps DISCONNECTED documents as they are.
     *
     * @param parentDocumentId Parent document ID or NULL for root documents.
     * @throws FileNotFoundException
     */
    void startAddingDocuments(@Nullable String parentDocumentId) throws FileNotFoundException {
        final String selection;
        final String[] args;
        if (parentDocumentId != null) {
            selection = COLUMN_PARENT_DOCUMENT_ID + " = ?";
            args = strings(parentDocumentId);
        } else {
            selection = COLUMN_PARENT_DOCUMENT_ID + " IS NULL";
            args = EMPTY_ARGS;
        }

        final SQLiteDatabase database = mDatabase.getSQLiteDatabase();
        database.beginTransaction();
        try {
            getParentOrHaltMapping(parentDocumentId);
            Preconditions.checkState(!mInMappingIds.contains(parentDocumentId));

            // Set all valid documents as invalidated.
            final ContentValues values = new ContentValues();
            values.put(COLUMN_ROW_STATE, ROW_STATE_INVALIDATED);
            database.update(
                    TABLE_DOCUMENTS,
                    values,
                    selection + " AND " + COLUMN_ROW_STATE + " = ?",
                    DatabaseUtils.appendSelectionArgs(args, strings(ROW_STATE_VALID)));

            database.setTransactionSuccessful();
            mInMappingIds.add(parentDocumentId);
        } finally {
            database.endTransaction();
        }
    }

    /**
     * Puts the documents into the database.
     * If the mapping mode is not heuristic, it just adds the rows to the database or updates the
     * existing rows with the new values. If the mapping mode is heuristic, it adds some new rows as
     * 'pending' state when that rows may be corresponding to existing 'invalidated' rows. Then
     * {@link #stopAddingDocuments(String)} turns the pending rows into 'valid'
     * rows. If the methods adds rows to database, it updates valueList with correct document ID.
     *
     * @param parentId Parent document ID.
     * @param valuesList Values for documents to be stored in the database.
     * @param rootExtraValuesList Values for root extra to be stored in the database.
     * @param selection SQL where closure to select rows that shares the same parent.
     * @param args Argument for selection SQL.
     * @return Whether the database content is changed.
     * @throws FileNotFoundException When parentId is not registered in the database.
     */
    private boolean putDocuments(
            String parentId,
            ContentValues[] valuesList,
            @Nullable ContentValues[] rootExtraValuesList,
            String selection,
            String[] args,
            String[] mappingKeys) throws FileNotFoundException {
        final SQLiteDatabase database = mDatabase.getSQLiteDatabase();
        boolean changed = false;
        database.beginTransaction();
        try {
            getParentOrHaltMapping(parentId);
            Preconditions.checkState(mInMappingIds.contains(parentId));
            final ContentValues oldRowSnapshot = new ContentValues();
            final ContentValues newRowSnapshot = new ContentValues();
            for (int i = 0; i < valuesList.length; i++) {
                final ContentValues values = valuesList[i];
                final ContentValues rootExtraValues;
                if (rootExtraValuesList != null) {
                    rootExtraValues = rootExtraValuesList[i];
                } else {
                    rootExtraValues = null;
                }
                try (final Cursor candidateCursor =
                        queryCandidate(selection, args, mappingKeys, values)) {
                    final long rowId;
                    if (candidateCursor == null) {
                        rowId = database.insert(TABLE_DOCUMENTS, null, values);
                        changed = true;
                    } else {
                        candidateCursor.moveToNext();
                        rowId = candidateCursor.getLong(0);
                        if (!changed) {
                            mDatabase.writeRowSnapshot(String.valueOf(rowId), oldRowSnapshot);
                        }
                        database.update(
                                TABLE_DOCUMENTS,
                                values,
                                SELECTION_DOCUMENT_ID,
                                strings(rowId));
                    }
                    // Document ID is a primary integer key of the table. So the returned row
                    // IDs should be same with the document ID.
                    values.put(Document.COLUMN_DOCUMENT_ID, rowId);
                    if (rootExtraValues != null) {
                        rootExtraValues.put(Root.COLUMN_ROOT_ID, rowId);
                        database.replace(TABLE_ROOT_EXTRA, null, rootExtraValues);
                    }

                    if (!changed) {
                        mDatabase.writeRowSnapshot(String.valueOf(rowId), newRowSnapshot);
                        // Put row state as string because SQLite returns snapshot values as string.
                        oldRowSnapshot.put(COLUMN_ROW_STATE, String.valueOf(ROW_STATE_VALID));
                        if (!oldRowSnapshot.equals(newRowSnapshot)) {
                            changed = true;
                        }
                    }
                }
            }

            database.setTransactionSuccessful();
            return changed;
        } finally {
            database.endTransaction();
        }
    }

    /**
     * Stops adding documents.
     * It handles 'invalidated' and 'disconnected' documents which we don't put corresponding
     * documents so far.
     * If the type adding document is 'device' or 'storage', the document may appear again
     * afterward. The method marks such documents as 'disconnected'. If the type of adding document
     * is 'object', it seems the documents are really removed from the remote MTP device. So the
     * method deletes the metadata from the database.
     *
     * @param parentId Parent document ID or null for root documents.
     * @return Whether the methods changes file metadata in database.
     * @throws FileNotFoundException
     */
    boolean stopAddingDocuments(@Nullable String parentId) throws FileNotFoundException {
        final String selection;
        final String[] args;
        if (parentId != null) {
            selection = COLUMN_PARENT_DOCUMENT_ID + " = ?";
            args = strings(parentId);
        } else {
            selection = COLUMN_PARENT_DOCUMENT_ID + " IS NULL";
            args = EMPTY_ARGS;
        }

        final SQLiteDatabase database = mDatabase.getSQLiteDatabase();
        database.beginTransaction();
        try {
            final Identifier parentIdentifier = getParentOrHaltMapping(parentId);
            Preconditions.checkState(mInMappingIds.contains(parentId));
            mInMappingIds.remove(parentId);

            boolean changed = false;
            // Delete/disconnect all invalidated/disconnected rows that cannot be mapped.
            // If parentIdentifier is null, added documents are devices.
            // if parentIdentifier is DOCUMENT_TYPE_DEVICE, added documents are storages.
            final boolean keepUnmatchedDocument =
                    parentIdentifier == null ||
                    parentIdentifier.mDocumentType == DOCUMENT_TYPE_DEVICE;
            if (keepUnmatchedDocument) {
                if (mDatabase.disconnectDocumentsRecursively(
                        COLUMN_ROW_STATE + " = ? AND " + selection,
                        DatabaseUtils.appendSelectionArgs(strings(ROW_STATE_INVALIDATED), args))) {
                    changed = true;
                }
            } else {
                if (mDatabase.deleteDocumentsAndRootsRecursively(
                        COLUMN_ROW_STATE + " IN (?, ?) AND " + selection,
                        DatabaseUtils.appendSelectionArgs(
                                strings(ROW_STATE_INVALIDATED, ROW_STATE_DISCONNECTED), args))) {
                    changed = true;
                }
            }

            database.setTransactionSuccessful();
            return changed;
        } finally {
            database.endTransaction();
        }
    }

    /**
     * Queries candidate for each mappingKey, and returns the first cursor that includes a
     * candidate.
     *
     * @param selection Pre-selection for candidate.
     * @param args Arguments for selection.
     * @param mappingKeys List of mapping key columns.
     * @param values Values of document that Mapper tries to map.
     * @return Cursor for mapping candidate or null when Mapper does not find any candidate.
     */
    private @Nullable Cursor queryCandidate(
            String selection, String[] args, String[] mappingKeys, ContentValues values) {
        for (final String mappingKey : mappingKeys) {
            final Cursor candidateCursor = queryCandidate(selection, args, mappingKey, values);
            if (candidateCursor.getCount() == 0) {
                candidateCursor.close();
                continue;
            }
            return candidateCursor;
        }
        return null;
    }

    /**
     * Looks for mapping candidate with given mappingKey.
     *
     * @param selection Pre-selection for candidate.
     * @param args Arguments for selection.
     * @param mappingKey Column name of mapping key.
     * @param values Values of document that Mapper tries to map.
     * @return Cursor for mapping candidate.
     */
    private Cursor queryCandidate(
            String selection, String[] args, String mappingKey, ContentValues values) {
        final SQLiteDatabase database = mDatabase.getSQLiteDatabase();
        return database.query(
                TABLE_DOCUMENTS,
                strings(Document.COLUMN_DOCUMENT_ID),
                selection + " AND " +
                COLUMN_ROW_STATE + " IN (?, ?) AND " +
                mappingKey + " = ?",
                DatabaseUtils.appendSelectionArgs(
                        args,
                        strings(ROW_STATE_INVALIDATED,
                                ROW_STATE_DISCONNECTED,
                                values.getAsString(mappingKey))),
                null,
                null,
                null,
                "1");
    }

    /**
     * Returns the parent identifier from parent document ID if the parent ID is found in the
     * database. Otherwise it halts mapping and throws FileNotFoundException.
     *
     * @param parentId Parent document ID
     * @return Parent identifier
     * @throws FileNotFoundException
     */
    private @Nullable Identifier getParentOrHaltMapping(
            @Nullable String parentId) throws FileNotFoundException {
        if (parentId == null) {
            return null;
        }
        try {
            return mDatabase.createIdentifier(parentId);
        } catch (FileNotFoundException error) {
            mInMappingIds.remove(parentId);
            throw error;
        }
    }
}
