// 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 main

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

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 || katiEvalStatsFlag {
		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 !katiEvalStatsFlag {
		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()
}

func dumpStats() {
	if !katiEvalStatsFlag {
		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()
}
