// Licensed to 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. Apache Software Foundation (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 dashboard

import (
	"context"
	"fmt"
	"math"
	"strings"
	"time"

	"github.com/apache/skywalking-cli/commands/interceptor"
	"github.com/apache/skywalking-cli/graphql/schema"
	"github.com/apache/skywalking-cli/graphql/utils"
	lib "github.com/apache/skywalking-cli/lib/heatmap"

	"github.com/mattn/go-runewidth"
	"github.com/mum4k/termdash"
	"github.com/mum4k/termdash/container/grid"
	"github.com/mum4k/termdash/linestyle"
	"github.com/mum4k/termdash/terminal/termbox"
	"github.com/mum4k/termdash/terminal/terminalapi"
	"github.com/urfave/cli"

	"github.com/apache/skywalking-cli/display/graph/gauge"
	"github.com/apache/skywalking-cli/display/graph/heatmap"
	"github.com/apache/skywalking-cli/display/graph/linear"
	"github.com/apache/skywalking-cli/graphql/dashboard"

	"github.com/mum4k/termdash/cell"
	"github.com/mum4k/termdash/container"
	"github.com/mum4k/termdash/widgets/button"
	"github.com/mum4k/termdash/widgets/linechart"
)

// rootID is the ID assigned to the root container.
const rootID = "root"

type layoutType int

const (
	// layoutMetrics displays all the widgets.
	layoutMetrics layoutType = iota

	// layoutLineChart focuses onto the line chart.
	layoutLineChart

	// layoutHeatMap focuses onto the heat map.
	layoutHeatMap
)

// strToLayoutType ensures the order of buttons is fixed.
var strToLayoutType = map[string]layoutType{
	"Metrics":         layoutMetrics,
	"ResponseLatency": layoutLineChart,
	"HeatMap":         layoutHeatMap,
}

// widgets holds the widgets used by the dashboard.
type widgets struct {
	gauges  []*gauge.MetricColumn
	linears []*linechart.LineChart
	heatmap *lib.HeatMap

	// buttons are used to change the layout.
	buttons []*button.Button
}

// linearTitles are titles of each line chart, load from the template file.
var linearTitles []string

// template determines how the global dashboard is displayed.
var template *dashboard.GlobalTemplate

var allWidgets *widgets

var initStartStr string
var initEndStr string

var curStartTime time.Time
var curEndTime time.Time

// setLayout sets the specified layout.
func setLayout(c *container.Container, lt layoutType) error {
	gridOpts, err := gridLayout(lt)
	if err != nil {
		return err
	}
	return c.Update(rootID, gridOpts...)
}

// newLayoutButtons returns buttons that dynamically switch the layouts.
func newLayoutButtons(c *container.Container) ([]*button.Button, error) {
	buttons := make([]*button.Button, len(strToLayoutType))

	opts := []button.Option{
		button.WidthFor(longestString(template.Buttons.Texts)),
		button.FillColor(cell.ColorNumber(template.Buttons.ColorNum)),
		button.Height(template.Buttons.Height),
	}

	for _, text := range template.Buttons.Texts {
		// declare a local variable lt to avoid closure.
		lt, ok := strToLayoutType[text]
		if !ok {
			return nil, fmt.Errorf("the %s is not supposed to be the button's text", text)
		}

		b, err := button.New(text, func() error {
			return setLayout(c, lt)
		}, opts...)
		if err != nil {
			return nil, err
		}

		buttons[int(lt)] = b
	}

	return buttons, nil
}

// gridLayout prepares container options that represent the desired screen layout.
func gridLayout(lt layoutType) ([]container.Option, error) {
	const buttonRowHeight = 15

	buttonColWidthPerc := 100 / len(allWidgets.buttons)
	var buttonCols []grid.Element

	for _, b := range allWidgets.buttons {
		buttonCols = append(buttonCols, grid.ColWidthPerc(buttonColWidthPerc, grid.Widget(b)))
	}

	rows := []grid.Element{
		grid.RowHeightPerc(buttonRowHeight, buttonCols...),
	}

	switch lt {
	case layoutMetrics:
		rows = append(rows,
			grid.RowHeightPerc(70, gauge.MetricColumnsElement(allWidgets.gauges)...),
		)

	case layoutLineChart:
		lcElements := linear.LineChartElements(allWidgets.linears, linearTitles)
		percentage := int(math.Min(99, float64((100-buttonRowHeight)/len(lcElements))))

		for _, e := range lcElements {
			rows = append(rows,
				grid.RowHeightPerc(percentage, e...),
			)
		}

	case layoutHeatMap:
		const heatmapColWidth = 85

		rows = append(rows,
			grid.RowHeightPerc(
				99-buttonRowHeight,
				grid.ColWidthPerc((99-heatmapColWidth)/2), // Use two empty cols to center the heatmap.
				grid.ColWidthPerc(heatmapColWidth, grid.Widget(allWidgets.heatmap)),
				grid.ColWidthPerc((99-heatmapColWidth)/2),
			),
		)
	}

	builder := grid.New()
	builder.Add(
		grid.RowHeightPerc(99, rows...),
	)
	gridOpts, err := builder.Build()
	if err != nil {
		return nil, err
	}
	return gridOpts, nil
}

// newWidgets creates all widgets used by the dashboard.
func newWidgets(data *dashboard.GlobalData) error {
	var columns []*gauge.MetricColumn
	var linears []*linechart.LineChart

	// Create gauges to display global metrics.
	for i, t := range template.Metrics {
		col, err := gauge.NewMetricColumn(data.Metrics[i], &t)
		if err != nil {
			return err
		}
		columns = append(columns, col)
	}

	// Create line charts to display global response latency.
	for _, input := range data.ResponseLatency {
		l, err := linear.NewLineChart(input)
		if err != nil {
			return err
		}
		linears = append(linears, l)
	}

	// Create a heat map.
	hp, err := heatmap.NewHeatMapWidget(data.HeatMap)
	if err != nil {
		return err
	}

	allWidgets.gauges = columns
	allWidgets.linears = linears
	allWidgets.heatmap = hp
	return nil
}

func Display(ctx *cli.Context, data *dashboard.GlobalData) error {
	t, err := termbox.New(termbox.ColorMode(terminalapi.ColorMode256))
	if err != nil {
		return err
	}
	defer t.Close()

	c, err := container.New(
		t,
		container.Border(linestyle.Light),
		container.BorderTitle("[Global Dashboard]-PRESS Q TO QUIT"),
		container.ID(rootID))
	if err != nil {
		return err
	}

	te, err := dashboard.LoadTemplate(ctx.String("template"))
	if err != nil {
		return err
	}
	template = te
	linearTitles = strings.Split(template.ResponseLatency.Labels, ", ")

	// Initialization
	allWidgets = &widgets{
		gauges:  nil,
		linears: nil,
		heatmap: nil,
		buttons: nil,
	}
	err = newWidgets(data)
	if err != nil {
		return err
	}
	lb, err := newLayoutButtons(c)
	if err != nil {
		return err
	}
	allWidgets.buttons = lb

	gridOpts, err := gridLayout(layoutMetrics)
	if err != nil {
		return err
	}

	if e := c.Update(rootID, gridOpts...); e != nil {
		return e
	}

	con, cancel := context.WithCancel(context.Background())
	quitter := func(keyboard *terminalapi.Keyboard) {
		if strings.EqualFold(keyboard.Key.String(), "q") {
			cancel()
		}
	}

	refreshInterval := time.Duration(ctx.Int("refresh")) * time.Second
	dt := utils.DurationType(ctx.String("durationType"))

	// Only when users use the relative time, the duration will be adjusted to refresh.
	if dt != utils.BothPresent {
		go refresh(con, ctx, refreshInterval)
	}

	err = termdash.Run(con, t, c, termdash.KeyboardSubscriber(quitter), termdash.RedrawInterval(refreshInterval))

	return err
}

// longestString returns the longest string in the string array.
func longestString(strs []string) (ret string) {
	maxLen := 0
	for _, s := range strs {
		if l := runewidth.StringWidth(s); l > maxLen {
			ret = s
			maxLen = l
		}
	}
	return
}

// refresh updates the duration and query the new data to update all of widgets, once every delay.
func refresh(con context.Context, ctx *cli.Context, interval time.Duration) {
	ticker := time.NewTicker(interval)
	defer ticker.Stop()

	initStartStr = ctx.String("start")
	initEndStr = ctx.String("end")

	_, start, err := interceptor.TryParseTime(initStartStr)
	if err != nil {
		return
	}
	_, end, err := interceptor.TryParseTime(initEndStr)
	if err != nil {
		return
	}

	curStartTime = start
	curEndTime = end

	for {
		select {
		case <-ticker.C:
			d, err := updateDuration(interval)
			if err != nil {
				continue
			}

			data := dashboard.Global(ctx, d)
			if err := updateAllWidgets(data); err != nil {
				continue
			}
		case <-con.Done():
			return
		}
	}
}

// updateDuration will check if the duration changes after adding the interval.
// If the duration doesn't change, an error will be returned, and the dashboard will not refresh.
// Otherwise, a new duration will be returned, which is used to get the latest global data.
func updateDuration(interval time.Duration) (schema.Duration, error) {
	step, _, err := interceptor.TryParseTime(initStartStr)
	if err != nil {
		return schema.Duration{}, err
	}

	curStartTime = curStartTime.Add(interval)
	curEndTime = curEndTime.Add(interval)

	curStartStr := curStartTime.Format(utils.StepFormats[step])
	curEndStr := curEndTime.Format(utils.StepFormats[step])

	if curStartStr == initStartStr && curEndStr == initEndStr {
		return schema.Duration{}, fmt.Errorf("the duration does not update")
	}

	initStartStr = curStartStr
	initEndStr = curEndStr
	return schema.Duration{
		Start: curStartStr,
		End:   curEndStr,
		Step:  step,
	}, nil
}

// updateAllWidgets will update all of widgets' data to be displayed.
func updateAllWidgets(data *dashboard.GlobalData) error {
	// Update gauges
	for i, mcData := range data.Metrics {
		if err := allWidgets.gauges[i].Update(mcData); err != nil {
			return err
		}
	}

	// Update line charts.
	for i, inputs := range data.ResponseLatency {
		if err := linear.SetLineChartSeries(allWidgets.linears[i], inputs); err != nil {
			return err
		}
	}

	// Update the heat map.
	heatmap.SetData(allWidgets.heatmap, data.HeatMap)

	return nil
}
