/*
 * Copyright (C) 2013 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.camera.session;

import android.content.ContentResolver;
import android.graphics.BitmapFactory;
import android.location.Location;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Looper;

import com.android.camera.app.MediaSaver;
import com.android.camera.app.MediaSaver.OnMediaSavedListener;
import com.android.camera.data.LocalData;
import com.android.camera.debug.Log;
import com.android.camera.exif.ExifInterface;
import com.android.camera.util.FileUtil;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;

/**
 * Implementation for the {@link CaptureSessionManager}.
 */
public class CaptureSessionManagerImpl implements CaptureSessionManager {

    private static final Log.Tag TAG = new Log.Tag("CaptureSessMgrImpl");
    public static final String TEMP_SESSIONS = "TEMP_SESSIONS";

    private class CaptureSessionImpl implements CaptureSession {
        /** A URI of the item being processed. */
        private Uri mUri;
        /** The title of the item being processed. */
        private final String mTitle;
        /** The location this session was created at. Used for media store.*/
        private Location mLocation;
        /** The current progress of this session in percent. */
        private int mProgressPercent = 0;
        /** A message ID for the current progress state. */
        private CharSequence mProgressMessage;
        /** A place holder for this capture session. */
        private PlaceholderManager.Session mPlaceHolderSession;
        private Uri mContentUri;
        /** These listeners get informed about progress updates. */
        private final HashSet<ProgressListener> mProgressListeners =
                new HashSet<ProgressListener>();

        /**
         * Creates a new {@link CaptureSession}.
         *
         * @param title the title of this session.
         * @param location the location of this session, used for media store.
         */
        private CaptureSessionImpl(String title, Location location) {
            mTitle = title;
            mLocation = location;
        }

        @Override
        public String getTitle() {
            return mTitle;
        }

        @Override
        public Location getLocation() {
            return mLocation;
        }

        @Override
        public void setLocation(Location location) {
            mLocation = location;
        }

        @Override
        public synchronized void setProgress(int percent) {
            mProgressPercent = percent;
            notifyTaskProgress(mUri, mProgressPercent);
            for (ProgressListener listener : mProgressListeners) {
                listener.onProgressChanged(percent);
            }
        }

        @Override
        public synchronized int getProgress() {
            return mProgressPercent;
        }

        @Override
        public synchronized CharSequence getProgressMessage() {
            return mProgressMessage;
        }

        @Override
        public synchronized void setProgressMessage(CharSequence message) {
            mProgressMessage = message;
            notifyTaskProgressText(mUri, message);
            for (ProgressListener listener : mProgressListeners) {
                listener.onStatusMessageChanged(message);
            }
        }

        @Override
        public synchronized void startSession(byte[] placeholder, CharSequence progressMessage) {
            mProgressMessage = progressMessage;

            final long now = System.currentTimeMillis();
            // TODO: This needs to happen outside the UI thread.
            mPlaceHolderSession = mPlaceholderManager.insertPlaceholder(mTitle, placeholder, now);
            mUri = mPlaceHolderSession.outputUri;
            mSessions.put(mUri.toString(), this);
            notifyTaskQueued(mUri);
        }

        @Override
        public synchronized void startSession(Uri uri, CharSequence progressMessage) {
            mUri = uri;
            mProgressMessage = progressMessage;
            mPlaceHolderSession = mPlaceholderManager.convertToPlaceholder(uri);

            mSessions.put(mUri.toString(), this);
            notifyTaskQueued(mUri);
        }

        @Override
        public synchronized void cancel() {
            if (mUri != null) {
                removeSession(mUri.toString());
            }
        }

        @Override
        public synchronized void saveAndFinish(byte[] data, int width, int height, int orientation,
                ExifInterface exif, OnMediaSavedListener listener) {
            if (mPlaceHolderSession == null) {
                throw new IllegalStateException(
                        "Cannot call saveAndFinish without calling startSession first.");
            }

            // TODO: This needs to happen outside the UI thread.
            mContentUri = mPlaceholderManager.finishPlaceholder(mPlaceHolderSession, mLocation,
                    orientation, exif, data, width, height, LocalData.MIME_TYPE_JPEG);

            removeSession(mUri.toString());
            notifyTaskDone(mPlaceHolderSession.outputUri);
        }

        @Override
        public void finish() {
            if (mPlaceHolderSession == null) {
                throw new IllegalStateException(
                        "Cannot call finish without calling startSession first.");
            }

            final String path = this.getPath();

            AsyncTask.SERIAL_EXECUTOR.execute(new Runnable() {
                @Override
                public void run() {
                    byte[] jpegDataTemp;
                    try {
                        jpegDataTemp = FileUtil.readFileToByteArray(new File(path));
                    } catch (IOException e) {
                        return;
                    }
                    final byte[] jpegData = jpegDataTemp;

                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inJustDecodeBounds = true;
                    BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length, options);
                    int width = options.outWidth;
                    int height = options.outHeight;
                    int rotation = 0;
                    ExifInterface exif = null;
                    try {
                        exif = new ExifInterface();
                        exif.readExif(jpegData);
                    } catch (IOException e) {
                        Log.w(TAG, "Could not read exif", e);
                        exif = null;
                    }
                    CaptureSessionImpl.this.saveAndFinish(jpegData, width, height, rotation, exif,
                            null);
                }
            });

        }

        @Override
        public String getPath() {
            if (mUri == null) {
                throw new IllegalStateException("Cannot retrieve URI of not started session.");
            }

            File tempDirectory = null;
            try {
                tempDirectory = new File(
                        getSessionDirectory(TEMP_SESSIONS), mTitle);
            } catch (IOException e) {
                Log.e(TAG, "Could not get temp session directory", e);
                throw new RuntimeException("Could not get temp session directory", e);
            }
            tempDirectory.mkdirs();
            File tempFile = new File(tempDirectory, mTitle  + ".jpg");
            try {
                if (!tempFile.exists()) {
                    tempFile.createNewFile();
                }
            } catch (IOException e) {
                Log.e(TAG, "Could not create temp session file", e);
                throw new RuntimeException("Could not create temp session file", e);
            }
            return tempFile.getPath();
        }

        @Override
        public Uri getUri() {
            return mUri;
        }

        @Override
        public Uri getContentUri() {
            return mContentUri;
        }

        @Override
        public boolean hasPath() {
            return mUri != null;
        }

        @Override
        public void onPreviewAvailable() {
            notifySessionPreviewAvailable(mPlaceHolderSession.outputUri);
        }

        @Override
        public void updatePreview(String previewPath) {

            final String path = this.getPath();

            AsyncTask.SERIAL_EXECUTOR.execute(new Runnable() {
                @Override
                public void run() {
                    byte[] jpegDataTemp;
                    try {
                        jpegDataTemp = FileUtil.readFileToByteArray(new File(path));
                    } catch (IOException e) {
                        return;
                    }
                    final byte[] jpegData = jpegDataTemp;

                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inJustDecodeBounds = true;
                    BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length, options);
                    int width = options.outWidth;
                    int height = options.outHeight;

                    mPlaceholderManager.replacePlaceholder(mPlaceHolderSession, jpegData, width, height);
                    onPreviewAvailable();
                }
            });
        }

        @Override
        public void finishWithFailure(CharSequence reason) {
            if (mPlaceHolderSession == null) {
                throw new IllegalStateException(
                        "Cannot call finish without calling startSession first.");
            }
            mProgressMessage = reason;

            removeSession(mUri.toString());
            mFailedSessionMessages.put(mPlaceHolderSession.outputUri, reason);
            notifyTaskFailed(mPlaceHolderSession.outputUri, reason);
        }

        @Override
        public void addProgressListener(ProgressListener listener) {
            listener.onStatusMessageChanged(mProgressMessage);
            listener.onProgressChanged(mProgressPercent);
            mProgressListeners.add(listener);
        }

        @Override
        public void removeProgressListener(ProgressListener listener) {
            mProgressListeners.remove(listener);
        }
    }

    private final MediaSaver mMediaSaver;
    private final PlaceholderManager mPlaceholderManager;
    private final SessionStorageManager mSessionStorageManager;
    private final ContentResolver mContentResolver;

    /** Failed session messages. Uri -> message. */
    private final HashMap<Uri, CharSequence> mFailedSessionMessages =
            new HashMap<Uri, CharSequence>();

    /**
     * We use this to fire events to the session listeners from the main thread.
     */
    private final Handler mMainHandler = new Handler(Looper.getMainLooper());

    /** Sessions in progress, keyed by URI. */
    private final Map<String, CaptureSession> mSessions;

    /** Listeners interested in task update events. */
    private final LinkedList<SessionListener> mTaskListeners = new LinkedList<SessionListener>();

    /**
     * Initializes a new {@link CaptureSessionManager} implementation.
     *
     * @param mediaSaver used to store the resulting media item
     * @param contentResolver required by the media saver
     * @param placeholderManager used to manage placeholders in the filmstrip
     *            before the final result is ready
     * @param sessionStorageManager used to tell modules where to store
     *            temporary session data
     */
    public CaptureSessionManagerImpl(MediaSaver mediaSaver, ContentResolver contentResolver,
            PlaceholderManager placeholderManager, SessionStorageManager sessionStorageManager) {
        mSessions = new HashMap<String, CaptureSession>();
        mMediaSaver = mediaSaver;
        mContentResolver = contentResolver;
        mPlaceholderManager = placeholderManager;
        mSessionStorageManager = sessionStorageManager;
    }

    @Override
    public CaptureSession createNewSession(String title, Location location) {
        return new CaptureSessionImpl(title, location);
    }

    @Override
    public CaptureSession createSession() {
        return new CaptureSessionImpl(null, null);
    }

    @Override
    public CaptureSession getSession(Uri sessionUri) {
        return mSessions.get(sessionUri.toString());
    }

    @Override
    public void saveImage(byte[] data, String title, long date, Location loc,
            int width, int height, int orientation, ExifInterface exif,
            OnMediaSavedListener listener) {
        mMediaSaver.addImage(data, title, date, loc, width, height, orientation, exif,
                listener, mContentResolver);
    }

    @Override
    public void addSessionListener(SessionListener listener) {
        synchronized (mTaskListeners) {
            mTaskListeners.add(listener);
        }
    }

    @Override
    public void removeSessionListener(SessionListener listener) {
        synchronized (mTaskListeners) {
            mTaskListeners.remove(listener);
        }
    }

    @Override
    public File getSessionDirectory(String subDirectory) throws IOException {
      return mSessionStorageManager.getSessionDirectory(subDirectory);
    }

    private void removeSession(String sessionUri) {
        mSessions.remove(sessionUri);
    }

    /**
     * Notifies all task listeners that the task with the given URI has been
     * queued.
     */
    private void notifyTaskQueued(final Uri uri) {
        mMainHandler.post(new Runnable() {
            @Override
            public void run() {
                synchronized (mTaskListeners) {
                    for (SessionListener listener : mTaskListeners) {
                        listener.onSessionQueued(uri);
                    }
                }
            }
        });
    }

    /**
     * Notifies all task listeners that the task with the given URI has been
     * finished.
     */
    private void notifyTaskDone(final Uri uri) {
        mMainHandler.post(new Runnable() {
            @Override
            public void run() {
                synchronized (mTaskListeners) {
                    for (SessionListener listener : mTaskListeners) {
                        listener.onSessionDone(uri);
                    }
                }
            }
        });
    }

    /**
     * Notifies all task listeners that the task with the given URI has been
     * failed to process.
     */
    private void notifyTaskFailed(final Uri uri, final CharSequence reason) {
        mMainHandler.post(new Runnable() {
            @Override
            public void run() {
                synchronized (mTaskListeners) {
                    for (SessionListener listener : mTaskListeners) {
                        listener.onSessionFailed(uri, reason);
                    }
                }
            }
        });
    }

    /**
     * Notifies all task listeners that the task with the given URI has
     * progressed to the given state.
     */
    private void notifyTaskProgress(final Uri uri, final int progressPercent) {
        mMainHandler.post(new Runnable() {
            @Override
            public void run() {
                synchronized (mTaskListeners) {
                    for (SessionListener listener : mTaskListeners) {
                        listener.onSessionProgress(uri, progressPercent);
                    }
                }
            }
        });
    }

    /**
     * Notifies all task listeners that the task with the given URI has
     * changed its progress message.
     */
    private void notifyTaskProgressText(final Uri uri, final CharSequence message) {
        mMainHandler.post(new Runnable() {
            @Override
            public void run() {
                synchronized (mTaskListeners) {
                    for (SessionListener listener : mTaskListeners) {
                        listener.onSessionProgressText(uri, message);
                    }
                }
            }
        });
    }

    /**
     * Notifies all task listeners that the task with the given URI has updated
     * its media.
     */
    private void notifySessionPreviewAvailable(final Uri uri) {
        mMainHandler.post(new Runnable() {
            @Override
            public void run() {
                synchronized (mTaskListeners) {
                    for (SessionListener listener : mTaskListeners) {
                        listener.onSessionPreviewAvailable(uri);
                    }
                }
            }
        });
    }

    @Override
    public boolean hasErrorMessage(Uri uri) {
        return mFailedSessionMessages.containsKey(uri);
    }

    @Override
    public CharSequence getErrorMesage(Uri uri) {
        return mFailedSessionMessages.get(uri);
    }

    @Override
    public void removeErrorMessage(Uri uri) {
        mFailedSessionMessages.remove(uri);
    }
}
