package goyaml

// #include "helpers.h"
import "C"

import (
    "reflect"
    "unsafe"
    "strconv"
)


type encoder struct {
    emitter C.yaml_emitter_t
    event C.yaml_event_t
    out []byte
    tmp []byte
    tmph *reflect.SliceHeader
    flow bool
}


//export outputHandler
func outputHandler(data unsafe.Pointer, buffer *C.uchar, size C.size_t) C.int {
    e := (*encoder)(data)
    e.tmph.Data = uintptr(unsafe.Pointer(buffer))
    e.tmph.Len = int(size)
    e.tmph.Cap = int(size)
    e.out = append(e.out, e.tmp...)
    return 1
}

func newEncoder() (e *encoder) {
    e = &encoder{}
    e.tmph = (*reflect.SliceHeader)(unsafe.Pointer(&e.tmp))
    if C.yaml_emitter_initialize(&e.emitter) == 0 {
        panic("Failed to initialize YAML emitter")
    }
    C.set_output_handler(&e.emitter)
    C.yaml_stream_start_event_initialize(&e.event, C.YAML_UTF8_ENCODING)
    e.emit()
    C.yaml_document_start_event_initialize(&e.event, nil, nil, nil, 1)
    e.emit()
    return e
}

func (e *encoder) finish() {
    C.yaml_document_end_event_initialize(&e.event, 1)
    e.emit()
    e.emitter.open_ended = 0
    C.yaml_stream_end_event_initialize(&e.event)
    e.emit()
}

func (e *encoder) destroy() {
    C.yaml_emitter_delete(&e.emitter)
}

func (e *encoder) emit() {
    // This will internally delete the e.event value.
    if C.yaml_emitter_emit(&e.emitter, &e.event) == 0 &&
       e.event._type != C.YAML_DOCUMENT_END_EVENT &&
       e.event._type != C.YAML_STREAM_END_EVENT {
        if e.emitter.error == C.YAML_EMITTER_ERROR {
            // XXX TESTME
            panic("YAML emitter error: " + C.GoString(e.emitter.problem))
        } else {
            // XXX TESTME
            panic("Unknown YAML emitter error")
        }
    }
}

func (e *encoder) fail(msg string) {
    if msg == "" {
        if e.emitter.problem != nil {
            msg = C.GoString(e.emitter.problem)
        } else {
            msg = "Unknown problem generating YAML content"
        }
    }
    panic(msg)
}

func (e *encoder) marshal(tag string, in reflect.Value) {
    var value interface{}
    if getter, ok := in.Interface().(Getter); ok {
        tag, value = getter.GetYAML()
        if value == nil {
            e.nilv()
            return
        }
        in = reflect.NewValue(value)
    }
    switch in := in.(type) {
    case *reflect.InterfaceValue:
        if in.IsNil() {
            e.nilv()
        } else {
            e.marshal(tag, in.Elem())
        }
    case *reflect.MapValue:
        e.mapv(tag, in)
    case *reflect.PtrValue:
        if in.IsNil() {
            e.nilv()
        } else {
            e.marshal(tag, in.Elem())
        }
    case *reflect.StructValue:
        e.structv(tag, in)
    case *reflect.SliceValue:
        e.slicev(tag, in)
    case *reflect.StringValue:
        e.stringv(tag, in)
    case *reflect.IntValue:
        e.intv(tag, in)
    case *reflect.UintValue:
        e.uintv(tag, in)
    case *reflect.FloatValue:
        e.floatv(tag, in)
    case *reflect.BoolValue:
        e.boolv(tag, in)
    default:
        panic("Can't marshal type yet: " + in.Type().String())
    }
}

func (e *encoder) mapv(tag string, in *reflect.MapValue) {
    e.mappingv(tag, func() {
        for _, k := range in.Keys() {
            e.marshal("", k)
            e.marshal("", in.Elem(k))
        }
    })
}

func (e *encoder) structv(tag string, in *reflect.StructValue) {
    fields, err := getStructFields(in.Type().(*reflect.StructType))
    if err != nil {
        panic(err)
    }
    e.mappingv(tag, func() {
        for i, info := range fields.List {
            value := in.Field(i)
            if info.Conditional && isZero(value) {
                continue
            }
            e.marshal("", reflect.NewValue(info.Key))
            e.flow = info.Flow
            e.marshal("", value)
        }
    })
}

func (e *encoder) mappingv(tag string, f func()) {
    var ctag *C.yaml_char_t
    var free func()
    cimplicit := C.int(1)
    if tag != "" {
        ctag, free = ystr(tag)
        defer free()
        cimplicit = 0
    }
    cstyle := C.yaml_mapping_style_t(C.YAML_BLOCK_MAPPING_STYLE)
    if e.flow {
        e.flow = false
        cstyle = C.YAML_FLOW_MAPPING_STYLE
    }
    C.yaml_mapping_start_event_initialize(&e.event, nil, ctag, cimplicit,
                                          cstyle)
    e.emit()
    f()
    C.yaml_mapping_end_event_initialize(&e.event)
    e.emit()
}

func (e *encoder) slicev(tag string, in *reflect.SliceValue) {
    var ctag *C.yaml_char_t
    var free func()
    var cimplicit C.int
    if tag != "" {
        ctag, free = ystr(tag)
        defer free()
        cimplicit = 0
    } else {
        cimplicit = 1
    }

    cstyle := C.yaml_sequence_style_t(C.YAML_BLOCK_SEQUENCE_STYLE)
    if e.flow {
        e.flow = false
        cstyle = C.YAML_FLOW_SEQUENCE_STYLE
    }
    C.yaml_sequence_start_event_initialize(&e.event, nil, ctag, cimplicit,
                                           cstyle)
    e.emit()
    n := in.Len()
    for i := 0; i < n; i++ {
        e.marshal("", in.Elem(i))
    }
    C.yaml_sequence_end_event_initialize(&e.event)
    e.emit()
}

func (e *encoder) stringv(tag string, in *reflect.StringValue) {
    var style C.yaml_scalar_style_t
    s := in.Get()
    if rtag, _ := resolve("", s); rtag != "!!str" {
        style = C.YAML_DOUBLE_QUOTED_SCALAR_STYLE
    } else {
        style = C.YAML_PLAIN_SCALAR_STYLE
    }
    e.emitScalar(s, "", tag, style)
}

func (e *encoder) boolv(tag string, in *reflect.BoolValue) {
    var s string
    if in.Get() {
        s = "true"
    } else {
        s = "false"
    }
    e.emitScalar(s, "", tag, C.YAML_PLAIN_SCALAR_STYLE)
}

func (e *encoder) intv(tag string, in *reflect.IntValue) {
    s := strconv.Itoa64(in.Get())
    e.emitScalar(s, "", tag, C.YAML_PLAIN_SCALAR_STYLE)
}

func (e *encoder) uintv(tag string, in *reflect.UintValue) {
    s := strconv.Uitoa64(in.Get())
    e.emitScalar(s, "", tag, C.YAML_PLAIN_SCALAR_STYLE)
}

func (e *encoder) floatv(tag string, in *reflect.FloatValue) {
    // FIXME: Handle 64 bits here.
    s := strconv.Ftoa32(float32(in.Get()), 'g', -1)
    switch s {
    case "+Inf": s = ".inf"
    case "-Inf": s = "-.inf"
    case "NaN": s = ".nan"
    }
    e.emitScalar(s, "", tag, C.YAML_PLAIN_SCALAR_STYLE)
}

func (e *encoder) nilv() {
    e.emitScalar("null", "", "", C.YAML_PLAIN_SCALAR_STYLE)
}

func (e *encoder) emitScalar(value, anchor, tag string,
                             style C.yaml_scalar_style_t) {
    var canchor, ctag, cvalue *C.yaml_char_t
    var cimplicit C.int
    var free func()
    if anchor != "" {
        canchor, free = ystr(anchor)
        defer free()
    }
    if tag != "" {
        ctag, free = ystr(tag)
        defer free()
        cimplicit = 0
        style = C.YAML_PLAIN_SCALAR_STYLE
    } else {
        cimplicit = 1
    }
    cvalue, free = ystr(value)
    defer free()
    size := C.int(len(value))
    if C.yaml_scalar_event_initialize(&e.event, canchor, ctag, cvalue, size,
                                      cimplicit, cimplicit, style) == 0 {
        e.fail("")
    }
    e.emit()
}

func ystr(s string) (ys *C.yaml_char_t, free func()) {
    up := unsafe.Pointer(C.CString(s))
    ys = (*C.yaml_char_t)(up)
    free = func() { C.free(up) }
    return ys, free
}
