package jp.sourceforge.nicoro;

import org.json.JSONObject;

import android.test.AndroidTestCase;

import junit.framework.AssertionFailedError;

import static jp.sourceforge.nicoro.NicoroAPIManager.ECO_TYPE_HIGH;
import static jp.sourceforge.nicoro.NicoroAPIManager.ECO_TYPE_MID;
import static jp.sourceforge.nicoro.NicoroAPIManager.ECO_TYPE_LOW;
import static jp.sourceforge.nicoro.VideoLoader.*;

public class VideoLoaderTest extends AndroidTestCase {
    private final String lastModifiedHigh = "lastModifiedHigh";
    private final String etagHigh = "etagHigh";
    private final long contentLengthHigh = 1;
    private final long cachedLengthHigh = 11;

    private final String lastModifiedMid = "lastModifiedMid";
    private final String etagMid = "etagMid";
    private final long contentLengthMid = 2;
    private final long cachedLengthMid = 12;

    private final String lastModifiedLow = "lastModifiedLow";
    private final String etagLow = "etagLow";
    private final long contentLengthLow = 3;
    private final long cachedLengthLow = 13;

    public void testReadInfo() throws Exception {
        JSONObject json = new JSONObject();
        json.put(HEADER_LAST_MODIFIED, lastModifiedHigh);
        json.put(HEADER_ETAG, etagHigh);
        json.put(HEADER_CONTENT_LENGTH, contentLengthHigh);
        json.put(KEY_CACHED_LENGTH, cachedLengthHigh);

        json.put(HEADER_LAST_MODIFIED + MID_VIDEO_SUFFIX, lastModifiedMid);
        json.put(HEADER_ETAG + MID_VIDEO_SUFFIX, etagMid);
        json.put(HEADER_CONTENT_LENGTH + MID_VIDEO_SUFFIX, contentLengthMid);
        json.put(KEY_CACHED_LENGTH + MID_VIDEO_SUFFIX, cachedLengthMid);

        json.put(HEADER_LAST_MODIFIED + LOW_VIDEO_SUFFIX, lastModifiedLow);
        json.put(HEADER_ETAG + LOW_VIDEO_SUFFIX, etagLow);
        json.put(HEADER_CONTENT_LENGTH + LOW_VIDEO_SUFFIX, contentLengthLow);
        json.put(KEY_CACHED_LENGTH + LOW_VIDEO_SUFFIX, cachedLengthLow);

        VideoLoader videoLoader = new VideoLoader("", "", "sm1", getContext(),
                "", android.os.Process.THREAD_PRIORITY_DEFAULT);

        InfoData infoData = new InfoData();
        videoLoader.readInfo(json, infoData);

        assertEquals(lastModifiedHigh, infoData.high.ifModifiedSince);
        assertEquals(etagHigh, infoData.high.ifRange);
        assertEquals(Long.toString(contentLengthHigh), infoData.high.lastContentLength);
        assertEquals(Long.toString(cachedLengthHigh), infoData.high.lastCacheLength);

        assertEquals(lastModifiedMid, infoData.mid.ifModifiedSince);
        assertEquals(etagMid, infoData.mid.ifRange);
        assertEquals(Long.toString(contentLengthMid), infoData.mid.lastContentLength);
        assertEquals(Long.toString(cachedLengthMid), infoData.mid.lastCacheLength);

        assertEquals(lastModifiedLow, infoData.low.ifModifiedSince);
        assertEquals(etagLow, infoData.low.ifRange);
        assertEquals(Long.toString(contentLengthLow), infoData.low.lastContentLength);
        assertEquals(Long.toString(cachedLengthLow), infoData.low.lastCacheLength);
    }

    public void testCreateJsonForSaveInfo() throws Throwable {
        JSONObject json = null;
        try {
            // 高画質
            VideoLoader videoLoader = new VideoLoader("", "", "sm1", getContext(),
                    "", android.os.Process.THREAD_PRIORITY_DEFAULT);
            assertEquals(ECO_TYPE_HIGH, videoLoader.getEcoType());
            videoLoader.setContentLengthForTest(contentLengthHigh);
            setDataCreateJsonForSaveInfoCommon(videoLoader);
            json = videoLoader.createJsonForSaveInfo(
                    lastModifiedHigh, etagHigh, cachedLengthHigh);
            assertCreateJsonForSaveInfoCommon(json);

            // 中画質
            videoLoader = new VideoLoader("mid", "", "sm1", getContext(),
                    "", android.os.Process.THREAD_PRIORITY_DEFAULT);
            assertEquals(ECO_TYPE_MID, videoLoader.getEcoType());
            videoLoader.setContentLengthForTest(contentLengthMid);
            setDataCreateJsonForSaveInfoCommon(videoLoader);
            json = videoLoader.createJsonForSaveInfo(
                    lastModifiedMid, etagMid, cachedLengthMid);
            assertCreateJsonForSaveInfoCommon(json);

            // 低画質
            videoLoader = new VideoLoader("low", "", "sm1", getContext(),
                    "", android.os.Process.THREAD_PRIORITY_DEFAULT);
            assertEquals(ECO_TYPE_LOW, videoLoader.getEcoType());
            videoLoader.setContentLengthForTest(contentLengthLow);
            setDataCreateJsonForSaveInfoCommon(videoLoader);
            json = videoLoader.createJsonForSaveInfo(
                    lastModifiedLow, etagLow, cachedLengthLow);
            assertCreateJsonForSaveInfoCommon(json);
        } catch (Throwable t) {
            if (json == null) {
                throw t;
            }
            AssertionFailedError error = new AssertionFailedError(
                    "JSONObject: " + json.toString());
            error.initCause(t);
            throw error;
        }
    }

    private void setDataCreateJsonForSaveInfoCommon(VideoLoader videoLoader) {
        InfoData infoData = videoLoader.getTempInfoDataForTest();
        infoData.high.ifModifiedSince = lastModifiedHigh;
        infoData.high.ifRange = etagHigh;
        infoData.high.lastContentLength = Long.toString(contentLengthHigh);
        infoData.high.lastCacheLength = Long.toString(cachedLengthHigh);

        infoData.mid.ifModifiedSince = lastModifiedMid;
        infoData.mid.ifRange = etagMid;
        infoData.mid.lastContentLength = Long.toString(contentLengthMid);
        infoData.mid.lastCacheLength = Long.toString(cachedLengthMid);

        infoData.low.ifModifiedSince = lastModifiedLow;
        infoData.low.ifRange = etagLow;
        infoData.low.lastContentLength = Long.toString(contentLengthLow);
        infoData.low.lastCacheLength = Long.toString(cachedLengthLow);
    }

    private void assertCreateJsonForSaveInfoCommon(JSONObject json) throws Exception {
        assertEquals(lastModifiedHigh, json.getString(HEADER_LAST_MODIFIED));
        assertEquals(etagHigh, json.getString(HEADER_ETAG));
        assertEquals(contentLengthHigh, json.getLong(HEADER_CONTENT_LENGTH));
        assertEquals(cachedLengthHigh, json.getLong(KEY_CACHED_LENGTH));

        assertEquals(lastModifiedMid, json.getString(HEADER_LAST_MODIFIED + MID_VIDEO_SUFFIX));
        assertEquals(etagMid, json.getString(HEADER_ETAG + MID_VIDEO_SUFFIX));
        assertEquals(contentLengthMid, json.getLong(HEADER_CONTENT_LENGTH + MID_VIDEO_SUFFIX));
        assertEquals(cachedLengthMid, json.getLong(KEY_CACHED_LENGTH + MID_VIDEO_SUFFIX));

        assertEquals(lastModifiedLow, json.getString(HEADER_LAST_MODIFIED + LOW_VIDEO_SUFFIX));
        assertEquals(etagLow, json.getString(HEADER_ETAG + LOW_VIDEO_SUFFIX));
        assertEquals(contentLengthLow, json.getLong(HEADER_CONTENT_LENGTH + LOW_VIDEO_SUFFIX));
        assertEquals(cachedLengthLow, json.getLong(KEY_CACHED_LENGTH + LOW_VIDEO_SUFFIX));

        assertTrue(json.getLong(KEY_LAST_PLAYED) > 0);
    }
}
