/**
 * 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.inputmethod.dictionarypack;

import android.app.DownloadManager;
import android.app.DownloadManager.Query;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;

public class DictionaryDownloadProgressBar extends ProgressBar {
    @SuppressWarnings("unused")
    private static final String TAG = DictionaryDownloadProgressBar.class.getSimpleName();
    private static final int NOT_A_DOWNLOADMANAGER_PENDING_ID = 0;

    private String mClientId;
    private String mWordlistId;
    private boolean mIsCurrentlyAttachedToWindow = false;
    private Thread mReporterThread = null;

    public DictionaryDownloadProgressBar(final Context context) {
        super(context);
    }

    public DictionaryDownloadProgressBar(final Context context, final AttributeSet attrs) {
        super(context, attrs);
    }

    public void setIds(final String clientId, final String wordlistId) {
        mClientId = clientId;
        mWordlistId = wordlistId;
    }

    static private int getDownloadManagerPendingIdFromWordlistId(final Context context,
            final String clientId, final String wordlistId) {
        final SQLiteDatabase db = MetadataDbHelper.getDb(context, clientId);
        final ContentValues wordlistValues =
                MetadataDbHelper.getContentValuesOfLatestAvailableWordlistById(db, wordlistId);
        if (null == wordlistValues) {
            // We don't know anything about a word list with this id. Bug? This should never
            // happen, but still return to prevent a crash.
            Log.e(TAG, "Unexpected word list ID: " + wordlistId);
            return NOT_A_DOWNLOADMANAGER_PENDING_ID;
        }
        return wordlistValues.getAsInteger(MetadataDbHelper.PENDINGID_COLUMN);
    }

    /*
     * This method will stop any running updater thread for this progress bar and create and run
     * a new one only if the progress bar is visible.
     * Hence, as a result of calling this method, the progress bar will have an updater thread
     * running if and only if the progress bar is visible.
     */
    private void updateReporterThreadRunningStatusAccordingToVisibility() {
        if (null != mReporterThread) mReporterThread.interrupt();
        if (mIsCurrentlyAttachedToWindow && View.VISIBLE == getVisibility()) {
            final int downloadManagerPendingId =
                    getDownloadManagerPendingIdFromWordlistId(getContext(), mClientId, mWordlistId);
            if (NOT_A_DOWNLOADMANAGER_PENDING_ID == downloadManagerPendingId) {
                // Can't get the ID. This is never supposed to happen, but still clear the updater
                // thread and return to avoid a crash.
                mReporterThread = null;
                return;
            }
            final UpdaterThread updaterThread =
                    new UpdaterThread(getContext(), downloadManagerPendingId);
            updaterThread.start();
            mReporterThread = updaterThread;
        } else {
            // We're not going to restart the thread anyway, so we may as well garbage collect it.
            mReporterThread = null;
        }
    }

    @Override
    protected void onAttachedToWindow() {
        mIsCurrentlyAttachedToWindow = true;
        updateReporterThreadRunningStatusAccordingToVisibility();
    }

    @Override
    protected void onDetachedFromWindow() {
        mIsCurrentlyAttachedToWindow = false;
        updateReporterThreadRunningStatusAccordingToVisibility();
    }

    private class UpdaterThread extends Thread {
        private final static int REPORT_PERIOD = 150; // how often to report progress, in ms
        final DownloadManager mDownloadManager;
        final int mId;
        public UpdaterThread(final Context context, final int id) {
            super();
            mDownloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
            mId = id;
        }
        @Override
        public void run() {
            try {
                // It's almost impossible that mDownloadManager is null (it would mean it has been
                // disabled between pressing the 'install' button and displaying the progress
                // bar), but just in case.
                if (null == mDownloadManager) return;
                final UpdateHelper updateHelper = new UpdateHelper();
                final Query query = new Query().setFilterById(mId);
                int lastProgress = 0;
                setIndeterminate(true);
                while (!isInterrupted()) {
                    final Cursor cursor = mDownloadManager.query(query);
                    if (null == cursor) {
                        // Can't contact DownloadManager: this should never happen.
                        return;
                    }
                    try {
                        if (cursor.moveToNext()) {
                            final int columnBytesDownloadedSoFar = cursor.getColumnIndex(
                                    DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);
                            final int bytesDownloadedSoFar =
                                    cursor.getInt(columnBytesDownloadedSoFar);
                            updateHelper.setProgressFromAnotherThread(bytesDownloadedSoFar);
                        } else {
                            // Download has finished and DownloadManager has already been asked to
                            // clean up the db entry.
                            updateHelper.setProgressFromAnotherThread(getMax());
                            return;
                        }
                    } finally {
                        cursor.close();
                    }
                    Thread.sleep(REPORT_PERIOD);
                }
            } catch (InterruptedException e) {
                // Do nothing and terminate normally.
            }
        }

        private class UpdateHelper implements Runnable {
            private int mProgress;
            @Override
            public void run() {
                setIndeterminate(false);
                setProgress(mProgress);
            }
            public void setProgressFromAnotherThread(final int progress) {
                if (mProgress != progress) {
                    mProgress = progress;
                    // For some unknown reason, setProgress just does not work from a separate
                    // thread, although the code in ProgressBar looks like it should. Thus, we
                    // resort to a runnable posted to the handler of the view.
                    final Handler handler = getHandler();
                    // It's possible to come here before this view has been laid out. If so,
                    // just ignore the call - it will be updated again later.
                    if (null == handler) return;
                    handler.post(this);
                }
            }
        }
    }
}
