// Copyright 2015 Google Inc. All rights reserved
//
// Licensed 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 kati

import (
	"fmt"
	"io"
	"os"
	"sort"
	"sync"
	"time"
)

type traceEventT struct {
	mu  sync.Mutex
	f   io.WriteCloser
	t0  time.Time
	pid int
}

const (
	traceEventMain = iota + 1
	traceEventFindCache
	traceEventFindCacheLeaves
	traceEventFindCacheFiles
)

var traceEvent traceEventT

// TraceEventStart starts trace event.
func TraceEventStart(f io.WriteCloser) {
	traceEvent.start(f)
}

// TraceEventStop stops trace event.
func TraceEventStop() {
	traceEvent.stop()
}

func (t *traceEventT) start(f io.WriteCloser) {
	t.f = f
	t.t0 = time.Now()
	fmt.Fprint(t.f, "[ ")
}

func (t *traceEventT) enabled() bool {
	return t.f != nil
}

func (t *traceEventT) stop() {
	fmt.Fprint(t.f, "\n]\n")
	t.f.Close()
}

type event struct {
	name, v string
	tid     int
	t       time.Time
	emit    bool
}

func (t *traceEventT) begin(name string, v Value, tid int) event {
	var e event
	e.tid = tid
	e.t = time.Now()
	if t.f != nil || EvalStatsFlag {
		e.name = name
		e.v = v.String()
	}
	if t.f != nil {
		e.emit = name == "include" || name == "shell" || name == "findcache"
		if e.emit {
			t.emit("B", e, e.t.Sub(t.t0))
		}
	}
	return e
}

func (t *traceEventT) emit(ph string, e event, ts time.Duration) {
	t.mu.Lock()
	defer t.mu.Unlock()

	if t.pid == 0 {
		t.pid = os.Getpid()
	} else {
		fmt.Fprintf(t.f, ",\n")
	}
	fmt.Fprintf(t.f, `{"pid":%d,"tid":%d,"ts":%d,"ph":%q,"cat":%q,"name":%q,"args":{}}`,
		t.pid,
		e.tid,
		ts.Nanoseconds()/1e3,
		ph,
		e.name,
		e.v,
	)
}

func (t *traceEventT) end(e event) {
	if t.f != nil {
		if e.emit {
			t.emit("E", e, time.Since(t.t0))
		}
	}
	stats.add(e.name, e.v, e.t)
}

type statsData struct {
	Name    string
	Count   int
	Longest time.Duration
	Total   time.Duration
}

type statsT struct {
	mu   sync.Mutex
	data map[string]statsData
}

var stats = &statsT{
	data: make(map[string]statsData),
}

func (s *statsT) add(name, v string, t time.Time) {
	if !EvalStatsFlag {
		return
	}
	d := time.Since(t)
	key := fmt.Sprintf("%s:%s", name, v)
	s.mu.Lock()
	sd := s.data[key]
	if d > sd.Longest {
		sd.Longest = d
	}
	sd.Total += d
	sd.Count++
	s.data[key] = sd
	s.mu.Unlock()
}

// DumpStats dumps statistics collected if EvalStatsFlag is set.
func DumpStats() {
	if !EvalStatsFlag {
		return
	}
	var sv byTotalTime
	for k, v := range stats.data {
		v.Name = k
		sv = append(sv, v)
	}
	sort.Sort(sv)
	fmt.Println("count,longest(ns),total(ns),longest,total,name")
	for _, s := range sv {
		fmt.Printf("%d,%d,%d,%v,%v,%s\n", s.Count, s.Longest, s.Total, s.Longest, s.Total, s.Name)
	}
}

type byTotalTime []statsData

func (b byTotalTime) Len() int      { return len(b) }
func (b byTotalTime) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
func (b byTotalTime) Less(i, j int) bool {
	return b[i].Total > b[j].Total
}

type shellStatsT struct {
	mu       sync.Mutex
	duration time.Duration
	count    int
}

var shellStats = &shellStatsT{}

func (s *shellStatsT) add(d time.Duration) {
	s.mu.Lock()
	s.duration += d
	s.count++
	s.mu.Unlock()
}

func (s *shellStatsT) Duration() time.Duration {
	s.mu.Lock()
	defer s.mu.Unlock()
	return s.duration
}

func (s *shellStatsT) Count() int {
	s.mu.Lock()
	defer s.mu.Unlock()
	return s.count
}
