// Copyright 2015 The LUCI Authors.
//
// 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 progress

import (
	"errors"
	"fmt"
	"io"
	"strconv"
	"strings"
	"sync"
	"time"

	"go.chromium.org/luci/client/internal/common"
)

// Group identifies a column group to keep progress for.
type Group int

// Section identifies a particular column in a column group.
type Section int

// Progress outputs information about the progress of a long task.
//
// It's implementation must be thread safe.
type Progress interface {
	io.Closer
	// Update increases the count of a column.
	Update(group Group, section Section, count int64)
}

// Formatter formats numbers in a Column.
type Formatter func(i int64) string

// Column represent a column to be printed in the progress status.
type Column struct {
	Name      string
	Formatter Formatter
	Value     int64
}

// New returns an initialized thread-safe Progress implementation.
//
// columns is the number of stages each item must go through, then with a set
// of numbers for each state, which will be displayed as a number in each box.
//
// For:
//   columns = [][]Column{{Name:"found"}, {"hashed", Name:"to hash"}}
// It'll print:
//   [found] [hashed/to hash]
func New(columns [][]Column, out io.Writer) Progress {
	p := &progress{
		start:    time.Now().UTC(),
		columns:  make([][]Column, len(columns)),
		interval: time.Second,
		EOL:      "\n",
		out:      out,
	}
	if common.IsTerminal(out) {
		p.interval = 50 * time.Millisecond
		p.EOL = "\r"
	}
	for i, c := range columns {
		p.columns[i] = make([]Column, len(c))
		for j, d := range c {
			p.columns[i][j] = d
			if p.columns[i][j].Formatter == nil {
				p.columns[i][j].Formatter = formatInt
			}
		}
	}
	if out != nil {
		go p.printLoop()
	}
	return p
}

// Private stuff.

type progress struct {
	// Immutable.
	start    time.Time
	interval time.Duration
	EOL      string
	out      io.Writer

	// Mutable.
	lock         sync.Mutex
	columns      [][]Column // Only the .Value are updated.
	valueChanged bool
}

func (p *progress) Update(group Group, section Section, count int64) {
	go func() {
		p.lock.Lock()
		defer p.lock.Unlock()
		p.columns[group][section].Value += count
		p.valueChanged = true
	}()
}

func (p *progress) Close() error {
	p.lock.Lock()
	defer p.lock.Unlock()
	if p.out == nil {
		return errors.New("was already closed")
	}
	_, _ = p.out.Write([]byte("\n"))
	p.out = nil
	return nil
}

func (p *progress) printLoop() {
	line := renderNames(p.columns) + "\n"
	p.lock.Lock()
	out := p.out
	p.lock.Unlock()
	if _, err := io.WriteString(out, line); err != nil {
		return
	}
	for {
		p.lock.Lock()
		out, line := p.printStep()
		p.lock.Unlock()
		if out == nil {
			return
		}
		if line != "" {
			if _, err := io.WriteString(out, line); err != nil {
				return
			}
		}
		time.Sleep(p.interval)
	}
}

func (p *progress) printStep() (io.Writer, string) {
	if p.out == nil || !p.valueChanged {
		return p.out, ""
	}
	p.valueChanged = false
	// Zap resolution at .1s level. We're slow anyway.
	duration := time.Since(p.start).Round(100 * time.Millisecond)
	return p.out, fmt.Sprintf("%s %s%s", renderValues(p.columns), duration, p.EOL)
}

func renderSectionName(section []Column) string {
	parts := make([]string, len(section))
	for i, s := range section {
		parts[i] = s.Name
	}
	return "[" + strings.Join(parts, "/") + "]"
}

func renderNames(c [][]Column) string {
	sections := make([]string, len(c))
	for i, section := range c {
		sections[i] = renderSectionName(section)
	}
	return strings.Join(sections, " ")
}

func renderSectionValue(section []Column) string {
	parts := make([]string, len(section))
	for i, part := range section {
		parts[i] = part.Formatter(part.Value)
	}
	return "[" + strings.Join(parts, "/") + "]"
}

func renderValues(c [][]Column) string {
	sections := make([]string, len(c))
	for i, section := range c {
		sections[i] = renderSectionValue(section)
	}
	return strings.Join(sections, " ")
}

func formatInt(i int64) string {
	return strconv.FormatInt(i, 10)
}
