package org.codehaus.jackson.smile;

import java.io.*;

import org.junit.Assert;

import org.codehaus.jackson.*;
import org.codehaus.jackson.map.ObjectMapper;

abstract class SmileTestBase
    extends main.BaseTest
{
    protected ObjectMapper smileMapper() {
        return smileMapper(false);
    }
    
    protected ObjectMapper smileMapper(boolean requireHeader) {
        return smileMapper(requireHeader, false, false);
    }
    
    protected ObjectMapper smileMapper(boolean requireHeader,
            boolean writeHeader, boolean writeEndMarker)
    {
        return new ObjectMapper(smileFactory(requireHeader, writeHeader, writeEndMarker));
    }

    protected SmileParser _smileParser(byte[] input) throws IOException {
        return _smileParser(input, false);
    }

    protected SmileParser _smileParser(InputStream input) throws IOException {
        return _smileParser(input, false);
    }
    
    protected SmileParser _smileParser(byte[] input, boolean requireHeader) throws IOException
    {
        SmileFactory f = smileFactory(requireHeader, false, false);
    	return _smileParser(f, input);
    }

    protected SmileParser _smileParser(InputStream input, boolean requireHeader) throws IOException
    {
        SmileFactory f = smileFactory(requireHeader, false, false);
        return _smileParser(f, input);
    }
    
    protected SmileParser _smileParser(SmileFactory f, byte[] input)
        throws IOException
    {
        return f.createJsonParser(input);
    }

    protected SmileParser _smileParser(SmileFactory f, InputStream input)
        throws IOException
    {
        return f.createJsonParser(input);
    }
    
    protected SmileFactory smileFactory(boolean requireHeader,
            boolean writeHeader, boolean writeEndMarker)
    {
        SmileFactory f = new SmileFactory();
        f.configure(SmileParser.Feature.REQUIRE_HEADER, requireHeader);
        f.configure(SmileGenerator.Feature.WRITE_HEADER, writeHeader);
        f.configure(SmileGenerator.Feature.WRITE_END_MARKER, writeEndMarker);
        return f;
    }
    
    protected byte[] _smileDoc(String json) throws IOException
    {
    	return _smileDoc(json, true);
    }

    protected byte[] _smileDoc(String json, boolean writeHeader) throws IOException
    {
        return _smileDoc(new SmileFactory(), json, writeHeader);
    }

    protected byte[] _smileDoc(SmileFactory smileFactory, String json, boolean writeHeader) throws IOException
    {
        JsonFactory jf = new JsonFactory();
    	JsonParser jp = jf.createJsonParser(json);
    	ByteArrayOutputStream out = new ByteArrayOutputStream();
    	JsonGenerator jg = smileGenerator(out, writeHeader);
    	
    	while (jp.nextToken() != null) {
    	    jg.copyCurrentEvent(jp);
    	}
    	jp.close();
    	jg.close();
    	return out.toByteArray();
    }

    protected SmileGenerator smileGenerator(ByteArrayOutputStream result, boolean addHeader)
        throws IOException
    {
        return smileGenerator(new SmileFactory(), result, addHeader);
    }

    protected SmileGenerator smileGenerator(SmileFactory f,
            ByteArrayOutputStream result, boolean addHeader)
        throws IOException
    {
        f.configure(SmileGenerator.Feature.WRITE_HEADER, addHeader);
        return f.createJsonGenerator(result, null);
    }
    
    protected void _verifyBytes(byte[] actBytes, byte... expBytes)
    {
        Assert.assertArrayEquals(expBytes, actBytes);
    }
}
