/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 common

import (
	"encoding/json"
	"errors"
	"fmt"
	"strconv"
)

//
// Represents a trace span.
//
// Compatibility notes:
// When converting to JSON, we store the 64-bit numbers as hexadecimal strings rather than as
// integers.  This is because JavaScript lacks the ability to handle 64-bit integers.  Numbers above
// about 55 bits will be rounded by Javascript.  Since the Javascript UI is a primary consumer of
// this JSON data, we have to simply pass it as a string.
//

type TraceInfoMap map[string]string

type TimelineAnnotation struct {
	Time int64  `json:"t"`
	Msg  string `json:"m"`
}

type SpanId uint64

func (id SpanId) String() string {
	return fmt.Sprintf("%016x", uint64(id))
}

func (id SpanId) Val() uint64 {
	return uint64(id)
}

func (id SpanId) MarshalJSON() ([]byte, error) {
	return []byte(`"` + fmt.Sprintf("%016x", uint64(id)) + `"`), nil
}

type SpanSlice []*Span

func (s SpanSlice) Len() int {
	return len(s)
}

func (s SpanSlice) Less(i, j int) bool {
	return s[i].Id < s[j].Id
}

func (s SpanSlice) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}

type SpanIdSlice []SpanId

func (s SpanIdSlice) Len() int {
	return len(s)
}

func (s SpanIdSlice) Less(i, j int) bool {
	return s[i] < s[j]
}

func (s SpanIdSlice) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}

const DOUBLE_QUOTE = 0x22

func (id *SpanId) UnmarshalJSON(b []byte) error {
	if b[0] != DOUBLE_QUOTE {
		return errors.New("Expected spanID to start with a string quote.")
	}
	if b[len(b)-1] != DOUBLE_QUOTE {
		return errors.New("Expected spanID to end with a string quote.")
	}
	return id.FromString(string(b[1 : len(b)-1]))
}

func (id *SpanId) FromString(str string) error {
	v, err := strconv.ParseUint(str, 16, 64)
	if err != nil {
		return err
	}
	*id = SpanId(v)
	return nil
}

type SpanData struct {
	Begin               int64                `json:"b"`
	End                 int64                `json:"e"`
	Description         string               `json:"d"`
	TraceId             SpanId               `json:"i"`
	Parents             []SpanId             `json:"p"`
	Info                TraceInfoMap         `json:"n,omitempty"`
	ProcessId           string               `json:"r"`
	TimelineAnnotations []TimelineAnnotation `json:"t,omitempty"`
}

type Span struct {
	Id SpanId `json:"s"`
	SpanData
}

func (span *Span) ToJson() []byte {
	jbytes, err := json.Marshal(*span)
	if err != nil {
		panic(err)
	}
	return jbytes
}

// Compute the span duration.  We ignore overflow since we never deal with negative times.
func (span *Span) Duration() int64 {
	return span.End - span.Begin
}
