/*
 * Copyright (C) 2010 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.browser.widget;

import android.appwidget.AppWidgetManager;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.MergeCursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.net.Uri;
import android.os.Binder;
import android.provider.BrowserContract;
import android.provider.BrowserContract.Bookmarks;
import android.text.TextUtils;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;

import com.android.browser.BrowserActivity;
import com.android.browser.R;
import com.android.browser.provider.BrowserProvider2;

import java.io.File;
import java.io.FilenameFilter;
import java.util.HashSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class BookmarkThumbnailWidgetService extends RemoteViewsService {

    static final String TAG = "BookmarkThumbnailWidgetService";
    static final String ACTION_CHANGE_FOLDER
            = "com.android.browser.widget.CHANGE_FOLDER";

    static final String STATE_CURRENT_FOLDER = "current_folder";
    static final String STATE_ROOT_FOLDER = "root_folder";

    private static final String[] PROJECTION = new String[] {
            BrowserContract.Bookmarks._ID,
            BrowserContract.Bookmarks.TITLE,
            BrowserContract.Bookmarks.URL,
            BrowserContract.Bookmarks.FAVICON,
            BrowserContract.Bookmarks.IS_FOLDER,
            BrowserContract.Bookmarks.POSITION, /* needed for order by */
            BrowserContract.Bookmarks.THUMBNAIL,
            BrowserContract.Bookmarks.PARENT};
    private static final int BOOKMARK_INDEX_ID = 0;
    private static final int BOOKMARK_INDEX_TITLE = 1;
    private static final int BOOKMARK_INDEX_URL = 2;
    private static final int BOOKMARK_INDEX_FAVICON = 3;
    private static final int BOOKMARK_INDEX_IS_FOLDER = 4;
    private static final int BOOKMARK_INDEX_THUMBNAIL = 6;
    private static final int BOOKMARK_INDEX_PARENT_ID = 7;

    @Override
    public RemoteViewsFactory onGetViewFactory(Intent intent) {
        int widgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
        if (widgetId < 0) {
            Log.w(TAG, "Missing EXTRA_APPWIDGET_ID!");
            return null;
        }
        return new BookmarkFactory(getApplicationContext(), widgetId);
    }

    static SharedPreferences getWidgetState(Context context, int widgetId) {
        return context.getSharedPreferences(
                String.format("widgetState-%d", widgetId),
                Context.MODE_PRIVATE);
    }

    static void deleteWidgetState(Context context, int widgetId) {
        File file = context.getSharedPrefsFile(
                String.format("widgetState-%d", widgetId));
        if (file.exists()) {
            if (!file.delete()) {
                file.deleteOnExit();
            }
        }
    }

    static void changeFolder(Context context, Intent intent) {
        int wid = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
        long fid = intent.getLongExtra(Bookmarks._ID, -1);
        if (wid >= 0 && fid >= 0) {
            SharedPreferences prefs = getWidgetState(context, wid);
            prefs.edit().putLong(STATE_CURRENT_FOLDER, fid).commit();
            AppWidgetManager.getInstance(context)
                    .notifyAppWidgetViewDataChanged(wid, R.id.bookmarks_list);
        }
    }

    static void setupWidgetState(Context context, int widgetId, long rootFolder) {
        SharedPreferences pref = getWidgetState(context, widgetId);
        pref.edit()
            .putLong(STATE_CURRENT_FOLDER, rootFolder)
            .putLong(STATE_ROOT_FOLDER, rootFolder)
            .apply();
    }

    /**
     *  Checks for any state files that may have not received onDeleted
     */
    static void removeOrphanedStates(Context context, int[] widgetIds) {
        File prefsDirectory = context.getSharedPrefsFile("null").getParentFile();
        File[] widgetStates = prefsDirectory.listFiles(new StateFilter(widgetIds));
        if (widgetStates != null) {
            for (File f : widgetStates) {
                Log.w(TAG, "Found orphaned state: " + f.getName());
                if (!f.delete()) {
                    f.deleteOnExit();
                }
            }
        }
    }

    static class StateFilter implements FilenameFilter {

        static final Pattern sStatePattern = Pattern.compile("widgetState-(\\d+)\\.xml");
        HashSet<Integer> mWidgetIds;

        StateFilter(int[] ids) {
            mWidgetIds = new HashSet<Integer>();
            for (int id : ids) {
                mWidgetIds.add(id);
            }
        }

        @Override
        public boolean accept(File dir, String filename) {
            Matcher m = sStatePattern.matcher(filename);
            if (m.matches()) {
                int id = Integer.parseInt(m.group(1));
                if (!mWidgetIds.contains(id)) {
                    return true;
                }
            }
            return false;
        }

    }

    static class BookmarkFactory implements RemoteViewsService.RemoteViewsFactory {
        private Cursor mBookmarks;
        private Context mContext;
        private int mWidgetId;
        private long mCurrentFolder = -1;
        private long mRootFolder = -1;
        private SharedPreferences mPreferences = null;

        public BookmarkFactory(Context context, int widgetId) {
            mContext = context.getApplicationContext();
            mWidgetId = widgetId;
        }

        void syncState() {
            if (mPreferences == null) {
                mPreferences = getWidgetState(mContext, mWidgetId);
            }
            long currentFolder = mPreferences.getLong(STATE_CURRENT_FOLDER, -1);
            mRootFolder = mPreferences.getLong(STATE_ROOT_FOLDER, -1);
            if (currentFolder != mCurrentFolder) {
                resetBookmarks();
                mCurrentFolder = currentFolder;
            }
        }

        void saveState() {
            if (mPreferences == null) {
                mPreferences = getWidgetState(mContext, mWidgetId);
            }
            mPreferences.edit()
                .putLong(STATE_CURRENT_FOLDER, mCurrentFolder)
                .putLong(STATE_ROOT_FOLDER, mRootFolder)
                .commit();
        }

        @Override
        public int getCount() {
            if (mBookmarks == null)
                return 0;
            return mBookmarks.getCount();
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public RemoteViews getLoadingView() {
            return new RemoteViews(
                    mContext.getPackageName(), R.layout.bookmarkthumbnailwidget_item);
        }

        @Override
        public RemoteViews getViewAt(int position) {
            if (!mBookmarks.moveToPosition(position)) {
                return null;
            }

            long id = mBookmarks.getLong(BOOKMARK_INDEX_ID);
            String title = mBookmarks.getString(BOOKMARK_INDEX_TITLE);
            String url = mBookmarks.getString(BOOKMARK_INDEX_URL);
            boolean isFolder = mBookmarks.getInt(BOOKMARK_INDEX_IS_FOLDER) != 0;

            RemoteViews views;
            // Two layouts are needed because of b/5387153
            if (isFolder) {
                views = new RemoteViews(mContext.getPackageName(),
                        R.layout.bookmarkthumbnailwidget_item_folder);
            } else {
                views = new RemoteViews(mContext.getPackageName(),
                        R.layout.bookmarkthumbnailwidget_item);
            }
            // Set the title of the bookmark. Use the url as a backup.
            String displayTitle = title;
            if (TextUtils.isEmpty(displayTitle)) {
                // The browser always requires a title for bookmarks, but jic...
                displayTitle = url;
            }
            views.setTextViewText(R.id.label, displayTitle);
            if (isFolder) {
                if (id == mCurrentFolder) {
                    id = mBookmarks.getLong(BOOKMARK_INDEX_PARENT_ID);
                    views.setImageViewResource(R.id.thumb, R.drawable.thumb_bookmark_widget_folder_back_holo);
                } else {
                    views.setImageViewResource(R.id.thumb, R.drawable.thumb_bookmark_widget_folder_holo);
                }
                views.setImageViewResource(R.id.favicon, R.drawable.ic_bookmark_widget_bookmark_holo_dark);
                views.setDrawableParameters(R.id.thumb, true, 0, -1, null, -1);
            } else {
                // RemoteViews require a valid bitmap config
                Options options = new Options();
                options.inPreferredConfig = Config.ARGB_8888;
                Bitmap thumbnail = null, favicon = null;
                byte[] blob = mBookmarks.getBlob(BOOKMARK_INDEX_THUMBNAIL);
                views.setDrawableParameters(R.id.thumb, true, 255, -1, null, -1);
                if (blob != null && blob.length > 0) {
                    thumbnail = BitmapFactory.decodeByteArray(
                            blob, 0, blob.length, options);
                    views.setImageViewBitmap(R.id.thumb, thumbnail);
                } else {
                    views.setImageViewResource(R.id.thumb,
                            R.drawable.browser_thumbnail);
                }
                blob = mBookmarks.getBlob(BOOKMARK_INDEX_FAVICON);
                if (blob != null && blob.length > 0) {
                    favicon = BitmapFactory.decodeByteArray(
                            blob, 0, blob.length, options);
                    views.setImageViewBitmap(R.id.favicon, favicon);
                } else {
                    views.setImageViewResource(R.id.favicon,
                            R.drawable.app_web_browser_sm);
                }
            }
            Intent fillin;
            if (isFolder) {
                fillin = new Intent(ACTION_CHANGE_FOLDER)
                        .putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mWidgetId)
                        .putExtra(Bookmarks._ID, id);
            } else {
                if (!TextUtils.isEmpty(url)) {
                    fillin = new Intent(Intent.ACTION_VIEW)
                            .addCategory(Intent.CATEGORY_BROWSABLE)
                            .setData(Uri.parse(url));
                } else {
                    fillin = new Intent(BrowserActivity.ACTION_SHOW_BROWSER);
                }
            }
            views.setOnClickFillInIntent(R.id.list_item, fillin);
            return views;
        }

        @Override
        public int getViewTypeCount() {
            return 2;
        }

        @Override
        public boolean hasStableIds() {
            return false;
        }

        @Override
        public void onCreate() {
        }

        @Override
        public void onDestroy() {
            if (mBookmarks != null) {
                mBookmarks.close();
                mBookmarks = null;
            }
            deleteWidgetState(mContext, mWidgetId);
        }

        @Override
        public void onDataSetChanged() {
            long token = Binder.clearCallingIdentity();
            syncState();
            if (mRootFolder < 0 || mCurrentFolder < 0) {
                // This shouldn't happen, but JIC default to the local account
                mRootFolder = BrowserProvider2.FIXED_ID_ROOT;
                mCurrentFolder = mRootFolder;
                saveState();
            }
            loadBookmarks();
            Binder.restoreCallingIdentity(token);
        }

        private void resetBookmarks() {
            if (mBookmarks != null) {
                mBookmarks.close();
                mBookmarks = null;
            }
        }

        void loadBookmarks() {
            resetBookmarks();

            Uri uri = ContentUris.withAppendedId(
                    BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER,
                    mCurrentFolder);
            mBookmarks = mContext.getContentResolver().query(uri, PROJECTION,
                    null, null, null);
            if (mCurrentFolder != mRootFolder) {
                uri = ContentUris.withAppendedId(
                        BrowserContract.Bookmarks.CONTENT_URI,
                        mCurrentFolder);
                Cursor c = mContext.getContentResolver().query(uri, PROJECTION,
                        null, null, null);
                mBookmarks = new MergeCursor(new Cursor[] { c, mBookmarks });
            }
        }
    }

}
