package com.atlassian.bitbucket.rest.util;

import com.atlassian.json.marshal.Jsonable;
import com.atlassian.bitbucket.rest.annotation.JsonSurrogate;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.map.SerializerProvider;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.codehaus.jackson.map.ser.std.SerializerBase;

import java.io.IOException;
import java.io.StringWriter;

import static com.google.common.base.Preconditions.checkNotNull;

@JsonSerialize(using = RestJsonable.RestJsonSerializer.class)
@JsonSurrogate(Jsonable.class)
public class RestJsonable {

    private final Jsonable value;

    public RestJsonable(Jsonable value) {
        this.value = checkNotNull(value, "value");
    }

    @Override
    public String toString() {
        StringWriter writer = new StringWriter();
        try {
            value.write(writer);
        } catch (IOException e) {
            throw new IllegalStateException(e);
        }
        return writer.toString();
    }

    /**
     * A Jackson serializer which delegates serialization responsibility to a given {@code Jsonable}
     */
    public static class RestJsonSerializer extends SerializerBase<RestJsonable> {
        public RestJsonSerializer() {
            super(RestJsonable.class);
        }
        @Override
        public void serialize(RestJsonable json, JsonGenerator jgen, SerializerProvider provider) throws IOException {
            jgen.writeRawValue(json.toString());
        }

    }
}
