/*
 * Copyright 2018 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.pump.db;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;

import androidx.annotation.AnyThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;

import com.android.pump.provider.Query;
import com.android.pump.util.Clog;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;

@WorkerThread
class VideoStore extends ContentObserver {
    private static final String TAG = Clog.tag(VideoStore.class);

    // TODO Replace the following with MediaStore.Video.Media.RELATIVE_PATH throughout the code.
    private static final String RELATIVE_PATH = "relative_path";

    // TODO Replace with Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q throughout the code.
    private static boolean isAtLeastRunningQ() {
        return Build.VERSION.SDK_INT > Build.VERSION_CODES.P
                || (Build.VERSION.SDK_INT == Build.VERSION_CODES.P
                && Build.VERSION.PREVIEW_SDK_INT > 0);
    }

    private final ContentResolver mContentResolver;
    private final ChangeListener mChangeListener;
    private final MediaProvider mMediaProvider;

    interface ChangeListener {
        void onMoviesAdded(@NonNull Collection<Movie> movies);
        void onSeriesAdded(@NonNull Collection<Series> series);
        void onEpisodesAdded(@NonNull Collection<Episode> episodes);
        void onOthersAdded(@NonNull Collection<Other> others);
    }

    @AnyThread
    VideoStore(@NonNull ContentResolver contentResolver, @NonNull ChangeListener changeListener,
            @NonNull MediaProvider mediaProvider) {
        super(null);

        Clog.i(TAG, "VideoStore(" + contentResolver + ", " + changeListener
                + ", " + mediaProvider + ")");
        mContentResolver = contentResolver;
        mChangeListener = changeListener;
        mMediaProvider = mediaProvider;

        // TODO(b/123706961) Do we need content observer for other content uris? (E.g. thumbnail)
        mContentResolver.registerContentObserver(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
                true, this);

        // TODO(b/123706961) When to call unregisterContentObserver?
        // mContentResolver.unregisterContentObserver(this);
    }

    void load() {
        Clog.i(TAG, "load()");
        Collection<Movie> movies = new ArrayList<>();
        Collection<Series> series = new ArrayList<>();
        Collection<Episode> episodes = new ArrayList<>();
        Collection<Other> others = new ArrayList<>();

        /* TODO get via count instead?
                Cursor countCursor = mContentResolver.query(CONTENT_URI,
                new String[] { "count(*) AS count" },
                null,
                null,
                null);
        countCursor.moveToFirst();
        int count = countCursor.getInt(0);
        Clog.i(TAG, "count = " + count);
        countCursor.close();
        */

        {
            Uri contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
            String[] projection;
            if (isAtLeastRunningQ()) {
                projection = new String[] {
                    MediaStore.Video.Media._ID,
                    MediaStore.Video.Media.MIME_TYPE,
                    RELATIVE_PATH,
                    MediaStore.Video.Media.DISPLAY_NAME
                };
            } else {
                projection = new String[] {
                    MediaStore.Video.Media._ID,
                    MediaStore.Video.Media.MIME_TYPE,
                    MediaStore.Video.Media.DATA
                };
            }
            String sortOrder = MediaStore.Video.Media._ID;
            Cursor cursor = mContentResolver.query(contentUri, projection, null, null, sortOrder);
            if (cursor != null) {
                try {
                    int idColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID);
                    int dataColumn;
                    int relativePathColumn;
                    int displayNameColumn;
                    int mimeTypeColumn = cursor.getColumnIndexOrThrow(
                            MediaStore.Video.Media.MIME_TYPE);

                    if (isAtLeastRunningQ()) {
                        dataColumn = -1;
                        relativePathColumn = cursor.getColumnIndexOrThrow(RELATIVE_PATH);
                        displayNameColumn = cursor.getColumnIndexOrThrow(
                                MediaStore.Video.Media.DISPLAY_NAME);
                    } else {
                        dataColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
                        relativePathColumn = -1;
                        displayNameColumn = -1;
                    }

                    for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
                        long id = cursor.getLong(idColumn);
                        String mimeType = cursor.getString(mimeTypeColumn);

                        File file;
                        if (isAtLeastRunningQ()) {
                            String relativePath = cursor.getString(relativePathColumn);
                            String displayName = cursor.getString(displayNameColumn);
                            file = new File(relativePath, displayName);
                        } else {
                            String data = cursor.getString(dataColumn);
                            file = new File(data);
                        }
                        Query query = Query.parse(Uri.fromFile(file));
                        if (query.isMovie()) {
                            Movie movie;
                            if (query.hasYear()) {
                                movie = new Movie(id, mimeType, query.getName(), query.getYear());
                            } else {
                                movie = new Movie(id, mimeType, query.getName());
                            }
                            movies.add(movie);
                        } else if (query.isEpisode()) {
                            Series serie = null;
                            for (Series s : series) {
                                if (s.getTitle().equals(query.getName())
                                        && s.hasYear() == query.hasYear()
                                        && (!s.hasYear() || s.getYear() == query.getYear())) {
                                    serie = s;
                                    break;
                                }
                            }
                            if (serie == null) {
                                if (query.hasYear()) {
                                    serie = new Series(query.getName(), query.getYear());
                                } else {
                                    serie = new Series(query.getName());
                                }
                                series.add(serie);
                            }

                            Episode episode = new Episode(id, mimeType, serie,
                                    query.getSeason(), query.getEpisode());
                            episodes.add(episode);

                            serie.addEpisode(episode);
                        } else {
                            Other other = new Other(id, mimeType, query.getName());
                            others.add(other);
                        }
                    }
                } finally {
                    cursor.close();
                }
            }
        }

        mChangeListener.onMoviesAdded(movies);
        mChangeListener.onSeriesAdded(series);
        mChangeListener.onEpisodesAdded(episodes);
        mChangeListener.onOthersAdded(others);
    }

    boolean loadData(@NonNull Movie movie) {
        Uri thumbnailUri = getThumbnailUri(movie.getId());
        if (thumbnailUri != null) {
            return movie.setThumbnailUri(thumbnailUri);
        }
        return false;
    }

    boolean loadData(@NonNull Series series) {
        return false;
    }

    boolean loadData(@NonNull Episode episode) {
        Uri thumbnailUri = getThumbnailUri(episode.getId());
        if (thumbnailUri != null) {
            return episode.setThumbnailUri(thumbnailUri);
        }
        return false;
    }

    boolean loadData(@NonNull Other other) {
        boolean updated = false;

        Uri contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
        String[] projection = {
            MediaStore.Video.Media.TITLE,
            MediaStore.Video.Media.DURATION,
            MediaStore.Video.Media.DATE_TAKEN,
            MediaStore.Video.Media.LATITUDE,
            MediaStore.Video.Media.LONGITUDE
        };
        String selection = MediaStore.Video.Media._ID + " = ?";
        String[] selectionArgs = { Long.toString(other.getId()) };
        Cursor cursor = mContentResolver.query(
                contentUri, projection, selection, selectionArgs, null);
        if (cursor != null) {
            try {
                int titleColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.TITLE);
                int durationColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION);
                int dateTakenColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATE_TAKEN);
                int latitudeColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.LATITUDE);
                int longitudeColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.LONGITUDE);

                if (cursor.moveToFirst()) {
                    if (!cursor.isNull(titleColumn)) {
                        String title = cursor.getString(titleColumn);
                        updated |= other.setTitle(title);
                    }
                    if (!cursor.isNull(durationColumn)) {
                        long duration = cursor.getLong(durationColumn);
                        updated |= other.setDuration(duration);
                    }
                    if (!cursor.isNull(dateTakenColumn)) {
                        long dateTaken = cursor.getLong(dateTakenColumn);
                        updated |= other.setDateTaken(dateTaken);
                    }
                    if (!cursor.isNull(latitudeColumn) && !cursor.isNull(longitudeColumn)) {
                        double latitude = cursor.getDouble(latitudeColumn);
                        double longitude = cursor.getDouble(longitudeColumn);
                        updated |= other.setLatLong(latitude, longitude);
                    }
                }
            } finally {
                cursor.close();
            }
        }

        Uri thumbnailUri = getThumbnailUri(other.getId());
        if (thumbnailUri != null) {
            updated |= other.setThumbnailUri(thumbnailUri);
        }

        return updated;
    }

    private @Nullable Uri getThumbnailUri(long id) {
        // TODO(b/130363861) No need to store the URI -- generate when requested instead
        return ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, id)
                .buildUpon().appendPath("thumbnail").build();
    }

    @Override
    public void onChange(boolean selfChange) {
        Clog.i(TAG, "onChange(" + selfChange + ")");
        onChange(selfChange, null);
    }

    @Override
    public void onChange(boolean selfChange, @Nullable Uri uri) {
        Clog.i(TAG, "onChange(" + selfChange + ", " + uri + ")");
        // TODO(b/123706961) Figure out what changed
        // onChange(false, content://media)
        // onChange(false, content://media/external)
        // onChange(false, content://media/external/audio/media/444)
        // onChange(false, content://media/external/video/media/328?blocking=1&orig_id=328&group_id=0)

        // TODO(b/123706961) Notify listener about changes
        // mChangeListener.xxx();
    }
}
