/*
 * Copyright (C) 2007 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 android.sax;

import android.graphics.Bitmap;
import android.sax.Element;
import android.sax.ElementListener;
import android.sax.EndTextElementListener;
import android.sax.RootElement;
import android.sax.StartElementListener;
import android.sax.TextElementListener;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.SmallTest;
import android.text.format.Time;
import android.util.Log;
import android.util.Xml;
import com.android.internal.util.XmlUtils;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import com.android.frameworks.saxtests.R;

public class SafeSaxTest extends AndroidTestCase {

    private static final String TAG = SafeSaxTest.class.getName();

    private static final String ATOM_NAMESPACE = "http://www.w3.org/2005/Atom";
    private static final String MEDIA_NAMESPACE = "http://search.yahoo.com/mrss/";
    private static final String YOUTUBE_NAMESPACE = "http://gdata.youtube.com/schemas/2007";
    private static final String GDATA_NAMESPACE = "http://schemas.google.com/g/2005";

    private static class ElementCounter implements ElementListener {
        int starts = 0;
        int ends = 0;

        public void start(Attributes attributes) {
            starts++;
        }

        public void end() {
            ends++;
        }
    }

    private static class TextElementCounter implements TextElementListener {
        int starts = 0;
        String bodies = "";

        public void start(Attributes attributes) {
            starts++;
        }

        public void end(String body) {
            this.bodies += body;
        }
    }

    @SmallTest
    public void testListener() throws Exception {
        String xml = "<feed xmlns='http://www.w3.org/2005/Atom'>\n"
                + "<entry>\n"
                + "<id>a</id>\n"
                + "</entry>\n"
                + "<entry>\n"
                + "<id>b</id>\n"
                + "</entry>\n"
                + "</feed>\n";

        RootElement root = new RootElement(ATOM_NAMESPACE, "feed");
        Element entry = root.requireChild(ATOM_NAMESPACE, "entry");
        Element id = entry.requireChild(ATOM_NAMESPACE, "id");

        ElementCounter rootCounter = new ElementCounter();
        ElementCounter entryCounter = new ElementCounter();
        TextElementCounter idCounter = new TextElementCounter();

        root.setElementListener(rootCounter);
        entry.setElementListener(entryCounter);
        id.setTextElementListener(idCounter);

        Xml.parse(xml, root.getContentHandler());

        assertEquals(1, rootCounter.starts);
        assertEquals(1, rootCounter.ends);
        assertEquals(2, entryCounter.starts);
        assertEquals(2, entryCounter.ends);
        assertEquals(2, idCounter.starts);
        assertEquals("ab", idCounter.bodies);
    }

    @SmallTest
    public void testMissingRequiredChild() throws Exception {
        String xml = "<feed></feed>";
        RootElement root = new RootElement("feed");
        root.requireChild("entry");

        try {
            Xml.parse(xml, root.getContentHandler());
            fail("expected exception not thrown");
        } catch (SAXException e) {
            // Expected.
        }
    }

    @SmallTest
    public void testMixedContent() throws Exception {
        String xml = "<feed><entry></entry></feed>";

        RootElement root = new RootElement("feed");
        root.setEndTextElementListener(new EndTextElementListener() {
            public void end(String body) {
            }
        });

        try {
            Xml.parse(xml, root.getContentHandler());
            fail("expected exception not thrown");
        } catch (SAXException e) {
            // Expected.
        }
    }

    @LargeTest
    public void testPerformance() throws Exception {
        InputStream in = mContext.getResources().openRawResource(R.raw.youtube);
        byte[] xmlBytes;
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int length;
            while ((length = in.read(buffer)) != -1) {
                out.write(buffer, 0, length);
            }
            xmlBytes = out.toByteArray();
        } finally {
            in.close();
        }

        Log.i("***", "File size: " + (xmlBytes.length / 1024) + "k");

        VideoAdapter videoAdapter = new VideoAdapter();
        ContentHandler handler = newContentHandler(videoAdapter);
        for (int i = 0; i < 2; i++) {
            pureSaxTest(new ByteArrayInputStream(xmlBytes));
            saxyModelTest(new ByteArrayInputStream(xmlBytes));
            saxyModelTest(new ByteArrayInputStream(xmlBytes), handler);
        }
    }

    private static void pureSaxTest(InputStream inputStream) throws IOException, SAXException {
        long start = System.currentTimeMillis();
        VideoAdapter videoAdapter = new VideoAdapter();
        Xml.parse(inputStream, Xml.Encoding.UTF_8, new YouTubeContentHandler(videoAdapter));
        long elapsed = System.currentTimeMillis() - start;
        Log.i(TAG, "pure SAX: " + elapsed + "ms");
    }

    private static void saxyModelTest(InputStream inputStream) throws IOException, SAXException {
        long start = System.currentTimeMillis();
        VideoAdapter videoAdapter = new VideoAdapter();
        Xml.parse(inputStream, Xml.Encoding.UTF_8, newContentHandler(videoAdapter));
        long elapsed = System.currentTimeMillis() - start;
        Log.i(TAG, "Saxy Model: " + elapsed + "ms");
    }

    private static void saxyModelTest(InputStream inputStream, ContentHandler contentHandler)
            throws IOException, SAXException {
        long start = System.currentTimeMillis();
        Xml.parse(inputStream, Xml.Encoding.UTF_8, contentHandler);
        long elapsed = System.currentTimeMillis() - start;
        Log.i(TAG, "Saxy Model (preloaded): " + elapsed + "ms");
    }

    private static class VideoAdapter {
        public void addVideo(YouTubeVideo video) {
        }
    }

    private static ContentHandler newContentHandler(VideoAdapter videoAdapter) {
        return new HandlerFactory().newContentHandler(videoAdapter);
    }

    private static class HandlerFactory {
        YouTubeVideo video;

        public ContentHandler newContentHandler(VideoAdapter videoAdapter) {
            RootElement root = new RootElement(ATOM_NAMESPACE, "feed");

            final VideoListener videoListener = new VideoListener(videoAdapter);

            Element entry = root.getChild(ATOM_NAMESPACE, "entry");

            entry.setElementListener(videoListener);

            entry.getChild(ATOM_NAMESPACE, "id")
                    .setEndTextElementListener(new EndTextElementListener() {
                        public void end(String body) {
                            video.videoId = body;
                        }
                    });

            entry.getChild(ATOM_NAMESPACE, "published")
                    .setEndTextElementListener(new EndTextElementListener() {
                        public void end(String body) {
                            // TODO(tomtaylor): programmatically get the timezone
                            video.dateAdded = new Time(Time.TIMEZONE_UTC);
                            video.dateAdded.parse3339(body);
                        }
                    });

            Element author = entry.getChild(ATOM_NAMESPACE, "author");
            author.getChild(ATOM_NAMESPACE, "name")
                    .setEndTextElementListener(new EndTextElementListener() {
                        public void end(String body) {
                            video.authorName = body;
                        }
                    });

            Element mediaGroup = entry.getChild(MEDIA_NAMESPACE, "group");

            mediaGroup.getChild(MEDIA_NAMESPACE, "thumbnail")
                    .setStartElementListener(new StartElementListener() {
                        public void start(Attributes attributes) {
                            String url = attributes.getValue("", "url");
                            if (video.thumbnailUrl == null && url.length() > 0) {
                                video.thumbnailUrl = url;
                            }
                        }
                    });

            mediaGroup.getChild(MEDIA_NAMESPACE, "content")
                    .setStartElementListener(new StartElementListener() {
                        public void start(Attributes attributes) {
                            String url = attributes.getValue("", "url");
                            if (url != null) {
                                video.videoUrl = url;
                            }
                        }
                    });

            mediaGroup.getChild(MEDIA_NAMESPACE, "player")
                    .setStartElementListener(new StartElementListener() {
                        public void start(Attributes attributes) {
                            String url = attributes.getValue("", "url");
                            if (url != null) {
                                video.playbackUrl = url;
                            }
                        }
                    });

            mediaGroup.getChild(MEDIA_NAMESPACE, "title")
                    .setEndTextElementListener(new EndTextElementListener() {
                        public void end(String body) {
                            video.title = body;
                        }
                    });

            mediaGroup.getChild(MEDIA_NAMESPACE, "category")
                    .setEndTextElementListener(new EndTextElementListener() {
                        public void end(String body) {
                            video.category = body;
                        }
                    });

            mediaGroup.getChild(MEDIA_NAMESPACE, "description")
                    .setEndTextElementListener(new EndTextElementListener() {
                        public void end(String body) {
                            video.description = body;
                        }
                    });

            mediaGroup.getChild(MEDIA_NAMESPACE, "keywords")
                    .setEndTextElementListener(new EndTextElementListener() {
                        public void end(String body) {
                            video.tags = body;
                        }
                    });

            mediaGroup.getChild(YOUTUBE_NAMESPACE, "duration")
                    .setStartElementListener(new StartElementListener() {
                        public void start(Attributes attributes) {
                            String seconds = attributes.getValue("", "seconds");
                            video.lengthInSeconds
                                    = XmlUtils.convertValueToInt(seconds, 0);
                        }
                    });

            mediaGroup.getChild(YOUTUBE_NAMESPACE, "statistics")
                    .setStartElementListener(new StartElementListener() {
                        public void start(Attributes attributes) {
                            String viewCount = attributes.getValue("", "viewCount");
                            video.viewCount
                                    = XmlUtils.convertValueToInt(viewCount, 0);
                        }
                    });

            entry.getChild(GDATA_NAMESPACE, "rating")
                    .setStartElementListener(new StartElementListener() {
                        public void start(Attributes attributes) {
                            String average = attributes.getValue("", "average");
                            video.rating = average == null
                                    ? 0.0f : Float.parseFloat(average);
                        }
                    });

            return root.getContentHandler();
        }

        class VideoListener implements ElementListener {

            final VideoAdapter videoAdapter;

            public VideoListener(VideoAdapter videoAdapter) {
                this.videoAdapter = videoAdapter;
            }

            public void start(Attributes attributes) {
                video = new YouTubeVideo();
            }

            public void end() {
                videoAdapter.addVideo(video);
                video = null;
            }
        }
    }

    private static class YouTubeContentHandler extends DefaultHandler {

        final VideoAdapter videoAdapter;

        YouTubeVideo video = null;
        StringBuilder builder = null;

        public YouTubeContentHandler(VideoAdapter videoAdapter) {
            this.videoAdapter = videoAdapter;
        }

        @Override
        public void startElement(String uri, String localName, String qName,
                Attributes attributes) throws SAXException {
            if (uri.equals(ATOM_NAMESPACE)) {
                if (localName.equals("entry")) {
                    video = new YouTubeVideo();
                    return;
                }

                if (video == null) {
                    return;
                }

                if (!localName.equals("id")
                        && !localName.equals("published")
                        && !localName.equals("name")) {
                    return;
                }
                this.builder = new StringBuilder();
                return;

            }

            if (video == null) {
                return;
            }

            if (uri.equals(MEDIA_NAMESPACE)) {
                if (localName.equals("thumbnail")) {
                    String url = attributes.getValue("", "url");
                    if (video.thumbnailUrl == null && url.length() > 0) {
                        video.thumbnailUrl = url;
                    }
                    return;
                }

                if (localName.equals("content")) {
                    String url = attributes.getValue("", "url");
                    if (url != null) {
                        video.videoUrl = url;
                    }
                    return;
                }

                if (localName.equals("player")) {
                    String url = attributes.getValue("", "url");
                    if (url != null) {
                        video.playbackUrl = url;
                    }
                    return;
                }

                if (localName.equals("title")
                        || localName.equals("category")
                        || localName.equals("description")
                        || localName.equals("keywords")) {
                    this.builder = new StringBuilder();
                    return;
                }

                return;
            }

            if (uri.equals(YOUTUBE_NAMESPACE)) {
                if (localName.equals("duration")) {
                    video.lengthInSeconds = XmlUtils.convertValueToInt(
                            attributes.getValue("", "seconds"), 0);
                    return;
                }

                if (localName.equals("statistics")) {
                    video.viewCount = XmlUtils.convertValueToInt(
                            attributes.getValue("", "viewCount"), 0);
                    return;
                }

                return;
            }

            if (uri.equals(GDATA_NAMESPACE)) {
                if (localName.equals("rating")) {
                    String average = attributes.getValue("", "average");
                    video.rating = average == null
                            ? 0.0f : Float.parseFloat(average);
                }
            }
        }

        @Override
        public void characters(char text[], int start, int length)
                throws SAXException {
            if (builder != null) {
                builder.append(text, start, length);
            }
        }

        String takeText() {
            try {
                return builder.toString();
            } finally {
                builder = null;
            }
        }

        @Override
        public void endElement(String uri, String localName, String qName)
                throws SAXException {
            if (video == null) {
                return;
            }

            if (uri.equals(ATOM_NAMESPACE)) {
                if (localName.equals("published")) {
                    // TODO(tomtaylor): programmatically get the timezone
                    video.dateAdded = new Time(Time.TIMEZONE_UTC);
                    video.dateAdded.parse3339(takeText());
                    return;
                }

                if (localName.equals("name")) {
                    video.authorName = takeText();
                    return;
                }

                if (localName.equals("id")) {
                    video.videoId = takeText();
                    return;
                }

                if (localName.equals("entry")) {
                    // Add the video!
                    videoAdapter.addVideo(video);
                    video = null;
                    return;
                }

                return;
            }

            if (uri.equals(MEDIA_NAMESPACE)) {
                if (localName.equals("description")) {
                    video.description = takeText();
                    return;
                }

                if (localName.equals("keywords")) {
                    video.tags = takeText();
                    return;
                }

                if (localName.equals("category")) {
                    video.category = takeText();
                    return;
                }

                if (localName.equals("title")) {
                    video.title = takeText();
                }
            }
        }
    }

    private static class YouTubeVideo {
        public String videoId;     // the id used to lookup on YouTube
        public String videoUrl;       // the url to play the video
        public String playbackUrl;    // the url to share for users to play video
        public String thumbnailUrl;   // the url of the thumbnail image
        public String title;
        public Bitmap bitmap;      // cached bitmap of the thumbnail
        public int lengthInSeconds;
        public int viewCount;      // number of times the video has been viewed
        public float rating;       // ranges from 0.0 to 5.0
        public Boolean triedToLoadThumbnail;
        public String authorName;
        public Time dateAdded;
        public String category;
        public String tags;
        public String description;
    }
}

