
/*
 * Copyright (C) 2011 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.homepages;

import android.content.Context;
import android.content.UriMatcher;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.MergeCursor;
import android.net.Uri;
import android.provider.BrowserContract.Bookmarks;
import android.provider.BrowserContract.History;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;

import com.android.browser.R;
import com.android.browser.homepages.Template.ListEntityIterator;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RequestHandler extends Thread {

    private static final String TAG = "RequestHandler";
    private static final int INDEX = 1;
    private static final int RESOURCE = 2;
    private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    Uri mUri;
    Context mContext;
    OutputStream mOutput;

    static {
        sUriMatcher.addURI(HomeProvider.AUTHORITY, "/", INDEX);
        sUriMatcher.addURI(HomeProvider.AUTHORITY, "res/*/*", RESOURCE);
    }

    public RequestHandler(Context context, Uri uri, OutputStream out) {
        mUri = uri;
        mContext = context.getApplicationContext();
        mOutput = out;
    }

    @Override
    public void run() {
        super.run();
        try {
            doHandleRequest();
        } catch (Exception e) {
            Log.e(TAG, "Failed to handle request: " + mUri, e);
        } finally {
            cleanup();
        }
    }

    void doHandleRequest() throws IOException {
        if ("file".equals(mUri.getScheme())) {
            writeFolderIndex();
            return;
        }
        int match = sUriMatcher.match(mUri);
        switch (match) {
        case INDEX:
            writeTemplatedIndex();
            break;
        case RESOURCE:
            writeResource(getUriResourcePath());
            break;
        }
    }

    byte[] htmlEncode(String s) {
        return TextUtils.htmlEncode(s).getBytes();
    }

    // We can reuse this for both History and Bookmarks queries because the
    // columns defined actually belong to the CommonColumn and ImageColumn
    // interfaces that both History and Bookmarks implement
    private static final String[] PROJECTION = new String[] {
        History.URL,
        History.TITLE,
        History.THUMBNAIL
    };
    private static final String SELECTION = History.URL
            + " NOT LIKE 'content:%' AND " + History.THUMBNAIL + " IS NOT NULL";
    void writeTemplatedIndex() throws IOException {
        Template t = Template.getCachedTemplate(mContext, R.raw.most_visited);
        Cursor historyResults = mContext.getContentResolver().query(
                History.CONTENT_URI, PROJECTION, SELECTION,
                null, History.VISITS + " DESC LIMIT 12");
        Cursor cursor = historyResults;
        try {
            if (cursor.getCount() < 12) {
                Cursor bookmarkResults = mContext.getContentResolver().query(
                        Bookmarks.CONTENT_URI, PROJECTION, SELECTION,
                        null, Bookmarks.DATE_CREATED + " DESC LIMIT 12");
                cursor = new MergeCursor(new Cursor[] { historyResults, bookmarkResults }) {
                    @Override
                    public int getCount() {
                        return Math.min(12, super.getCount());
                    }
                };
            }
            t.assignLoop("most_visited", new Template.CursorListEntityWrapper(cursor) {
                @Override
                public void writeValue(OutputStream stream, String key) throws IOException {
                    Cursor cursor = getCursor();
                    if (key.equals("url")) {
                        stream.write(htmlEncode(cursor.getString(0)));
                    } else if (key.equals("title")) {
                        stream.write(htmlEncode(cursor.getString(1)));
                    } else if (key.equals("thumbnail")) {
                        stream.write("data:image/png;base64,".getBytes());
                        byte[] thumb = cursor.getBlob(2);
                        stream.write(Base64.encode(thumb, Base64.DEFAULT));
                    }
                }
            });
            t.write(mOutput);
        } finally {
            cursor.close();
        }
    }

    private static final Comparator<File> sFileComparator = new Comparator<File>() {
        @Override
        public int compare(File lhs, File rhs) {
            if (lhs.isDirectory() != rhs.isDirectory()) {
                return lhs.isDirectory() ? -1 : 1;
            }
            return lhs.getName().compareTo(rhs.getName());
        }
    };

    void writeFolderIndex() throws IOException {
        File f = new File(mUri.getPath());
        final File[] files = f.listFiles();
        Arrays.sort(files, sFileComparator);
        Template t = Template.getCachedTemplate(mContext, R.raw.folder_view);
        t.assign("path", mUri.getPath());
        t.assign("parent_url", f.getParent() != null ? f.getParent() : f.getPath());
        t.assignLoop("files", new ListEntityIterator() {
            int index = -1;

            @Override
            public void writeValue(OutputStream stream, String key) throws IOException {
                File f = files[index];
                if ("name".equals(key)) {
                    stream.write(f.getName().getBytes());
                }
                if ("url".equals(key)) {
                    stream.write(("file://" + f.getAbsolutePath()).getBytes());
                }
                if ("type".equals(key)) {
                    stream.write((f.isDirectory() ? "dir" : "file").getBytes());
                }
                if ("size".equals(key)) {
                    if (f.isFile()) {
                        stream.write(readableFileSize(f.length()).getBytes());
                    }
                }
                if ("last_modified".equals(key)) {
                    String date = DateFormat.getDateTimeInstance(
                            DateFormat.SHORT, DateFormat.SHORT)
                            .format(f.lastModified());
                    stream.write(date.getBytes());
                }
                if ("alt".equals(key)) {
                    if (index % 2 == 0) {
                        stream.write("alt".getBytes());
                    }
                }
            }

            @Override
            public ListEntityIterator getListIterator(String key) {
                return null;
            }

            @Override
            public void reset() {
                index = -1;
            }

            @Override
            public boolean moveToNext() {
                return (++index) < files.length;
            }
        });
        t.write(mOutput);
    }

    static String readableFileSize(long size) {
        if(size <= 0) return "0";
        final String[] units = new String[] { "B", "KB", "MB", "GB", "TB" };
        int digitGroups = (int) (Math.log10(size) / Math.log10(1024));
        return new DecimalFormat("#,##0.#").format(
                size / Math.pow(1024, digitGroups)) + " " + units[digitGroups];
    }

    String getUriResourcePath() {
        final Pattern pattern = Pattern.compile("/?res/([\\w/]+)");
        Matcher m = pattern.matcher(mUri.getPath());
        if (m.matches()) {
            return m.group(1);
        } else {
            return mUri.getPath();
        }
    }

    void writeResource(String fileName) throws IOException {
        Resources res = mContext.getResources();
        String packageName = R.class.getPackage().getName();
        int id = res.getIdentifier(fileName, null, packageName);
        if (id != 0) {
            InputStream in = res.openRawResource(id);
            byte[] buf = new byte[4096];
            int read;
            while ((read = in.read(buf)) > 0) {
                mOutput.write(buf, 0, read);
            }
        }
    }

    void writeString(String str) throws IOException {
        mOutput.write(str.getBytes());
    }

    void writeString(String str, int offset, int count) throws IOException {
        mOutput.write(str.getBytes(), offset, count);
    }

    void cleanup() {
        try {
            mOutput.close();
        } catch (Exception e) {
            Log.e(TAG, "Failed to close pipe!", e);
        }
    }

}
