// Copyright 2019 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 terminal

import (
	"fmt"
	"io"
	"os"
	"os/signal"
	"strconv"
	"strings"
	"sync"
	"syscall"
	"time"

	"android/soong/ui/status"
)

const tableHeightEnVar = "SOONG_UI_TABLE_HEIGHT"

type actionTableEntry struct {
	action    *status.Action
	startTime time.Time
}

type smartStatusOutput struct {
	writer    io.Writer
	formatter formatter

	lock sync.Mutex

	haveBlankLine bool

	tableMode             bool
	tableHeight           int
	requestedTableHeight  int
	termWidth, termHeight int

	runningActions  []actionTableEntry
	ticker          *time.Ticker
	done            chan bool
	sigwinch        chan os.Signal
	sigwinchHandled chan bool

	// Once there is a failure, we stop printing command output so the error
	// is easier to find
	haveFailures bool
	// If we are dropping errors, then at the end, we report a message to go
	// look in the verbose log if you want that command output.
	postFailureActionCount int
}

// NewSmartStatusOutput returns a StatusOutput that represents the
// current build status similarly to Ninja's built-in terminal
// output.
func NewSmartStatusOutput(w io.Writer, formatter formatter) status.StatusOutput {
	s := &smartStatusOutput{
		writer:    w,
		formatter: formatter,

		haveBlankLine: true,

		tableMode: true,

		done:     make(chan bool),
		sigwinch: make(chan os.Signal),
	}

	if env, ok := os.LookupEnv(tableHeightEnVar); ok {
		h, _ := strconv.Atoi(env)
		s.tableMode = h > 0
		s.requestedTableHeight = h
	}

	if w, h, ok := termSize(s.writer); ok {
		s.termWidth, s.termHeight = w, h
		s.computeTableHeight()
	} else {
		s.tableMode = false
	}

	if s.tableMode {
		// Add empty lines at the bottom of the screen to scroll back the existing history
		// and make room for the action table.
		// TODO: read the cursor position to see if the empty lines are necessary?
		for i := 0; i < s.tableHeight; i++ {
			fmt.Fprintln(w)
		}

		// Hide the cursor to prevent seeing it bouncing around
		fmt.Fprintf(s.writer, ansi.hideCursor())

		// Configure the empty action table
		s.actionTable()

		// Start a tick to update the action table periodically
		s.startActionTableTick()
	}

	s.startSigwinch()

	return s
}

func (s *smartStatusOutput) Message(level status.MsgLevel, message string) {
	if level < status.StatusLvl {
		return
	}

	str := s.formatter.message(level, message)

	s.lock.Lock()
	defer s.lock.Unlock()

	if level > status.StatusLvl {
		s.print(str)
	} else {
		s.statusLine(str)
	}
}

func (s *smartStatusOutput) StartAction(action *status.Action, counts status.Counts) {
	startTime := time.Now()

	str := action.Description
	if str == "" {
		str = action.Command
	}

	progress := s.formatter.progress(counts)

	s.lock.Lock()
	defer s.lock.Unlock()

	s.runningActions = append(s.runningActions, actionTableEntry{
		action:    action,
		startTime: startTime,
	})

	s.statusLine(progress + str)
}

func (s *smartStatusOutput) FinishAction(result status.ActionResult, counts status.Counts) {
	str := result.Description
	if str == "" {
		str = result.Command
	}

	progress := s.formatter.progress(counts) + str

	output := s.formatter.result(result)

	s.lock.Lock()
	defer s.lock.Unlock()

	for i, runningAction := range s.runningActions {
		if runningAction.action == result.Action {
			s.runningActions = append(s.runningActions[:i], s.runningActions[i+1:]...)
			break
		}
	}

	s.statusLine(progress)

	// Stop printing when there are failures, but don't skip actions that also have their own errors.
	if output != "" {
		if !s.haveFailures || result.Error != nil {
			s.requestLine()
			s.print(output)
		} else {
			s.postFailureActionCount++
		}
	}

	if result.Error != nil {
		s.haveFailures = true
	}
}

func (s *smartStatusOutput) Flush() {
	if s.tableMode {
		// Stop the action table tick outside of the lock to avoid lock ordering issues between s.done and
		// s.lock, the goroutine in startActionTableTick can get blocked on the lock and be unable to read
		// from the channel.
		s.stopActionTableTick()
	}

	s.lock.Lock()
	defer s.lock.Unlock()

	s.stopSigwinch()

	if s.postFailureActionCount > 0 {
		s.requestLine()
		if s.postFailureActionCount == 1 {
			s.print(fmt.Sprintf("There was 1 action that completed after the action that failed. See verbose.log.gz for its output."))
		} else {
			s.print(fmt.Sprintf("There were %d actions that completed after the action that failed. See verbose.log.gz for their output.", s.postFailureActionCount))
		}
	}

	s.requestLine()

	s.runningActions = nil

	if s.tableMode {
		// Update the table after clearing runningActions to clear it
		s.actionTable()

		// Reset the scrolling region to the whole terminal
		fmt.Fprintf(s.writer, ansi.resetScrollingMargins())
		_, height, _ := termSize(s.writer)
		// Move the cursor to the top of the now-blank, previously non-scrolling region
		fmt.Fprintf(s.writer, ansi.setCursor(height-s.tableHeight, 1))
		// Turn the cursor back on
		fmt.Fprintf(s.writer, ansi.showCursor())
	}
}

func (s *smartStatusOutput) Write(p []byte) (int, error) {
	s.lock.Lock()
	defer s.lock.Unlock()
	s.print(string(p))
	return len(p), nil
}

func (s *smartStatusOutput) requestLine() {
	if !s.haveBlankLine {
		fmt.Fprintln(s.writer)
		s.haveBlankLine = true
	}
}

func (s *smartStatusOutput) print(str string) {
	if !s.haveBlankLine {
		fmt.Fprint(s.writer, "\r", ansi.clearToEndOfLine())
		s.haveBlankLine = true
	}
	fmt.Fprint(s.writer, str)
	if len(str) == 0 || str[len(str)-1] != '\n' {
		fmt.Fprint(s.writer, "\n")
	}
}

func (s *smartStatusOutput) statusLine(str string) {
	idx := strings.IndexRune(str, '\n')
	if idx != -1 {
		str = str[0:idx]
	}

	// Limit line width to the terminal width, otherwise we'll wrap onto
	// another line and we won't delete the previous line.
	str = elide(str, s.termWidth)

	// Move to the beginning on the line, turn on bold, print the output,
	// turn off bold, then clear the rest of the line.
	start := "\r" + ansi.bold()
	end := ansi.regular() + ansi.clearToEndOfLine()
	fmt.Fprint(s.writer, start, str, end)
	s.haveBlankLine = false
}

func elide(str string, width int) string {
	if width > 0 && len(str) > width {
		// TODO: Just do a max. Ninja elides the middle, but that's
		// more complicated and these lines aren't that important.
		str = str[:width]
	}

	return str
}

func (s *smartStatusOutput) startActionTableTick() {
	s.ticker = time.NewTicker(time.Second)
	go func() {
		for {
			select {
			case <-s.ticker.C:
				s.lock.Lock()
				s.actionTable()
				s.lock.Unlock()
			case <-s.done:
				return
			}
		}
	}()
}

func (s *smartStatusOutput) stopActionTableTick() {
	s.ticker.Stop()
	s.done <- true
}

func (s *smartStatusOutput) startSigwinch() {
	signal.Notify(s.sigwinch, syscall.SIGWINCH)
	go func() {
		for _ = range s.sigwinch {
			s.lock.Lock()
			s.updateTermSize()
			if s.tableMode {
				s.actionTable()
			}
			s.lock.Unlock()
			if s.sigwinchHandled != nil {
				s.sigwinchHandled <- true
			}
		}
	}()
}

func (s *smartStatusOutput) stopSigwinch() {
	signal.Stop(s.sigwinch)
	close(s.sigwinch)
}

// computeTableHeight recomputes s.tableHeight based on s.termHeight and s.requestedTableHeight.
func (s *smartStatusOutput) computeTableHeight() {
	tableHeight := s.requestedTableHeight
	if tableHeight == 0 {
		tableHeight = s.termHeight / 4
		if tableHeight < 1 {
			tableHeight = 1
		} else if tableHeight > 10 {
			tableHeight = 10
		}
	}
	if tableHeight > s.termHeight-1 {
		tableHeight = s.termHeight - 1
	}
	s.tableHeight = tableHeight
}

// updateTermSize recomputes the table height after a SIGWINCH and pans any existing text if
// necessary.
func (s *smartStatusOutput) updateTermSize() {
	if w, h, ok := termSize(s.writer); ok {
		oldScrollingHeight := s.termHeight - s.tableHeight

		s.termWidth, s.termHeight = w, h

		if s.tableMode {
			s.computeTableHeight()

			scrollingHeight := s.termHeight - s.tableHeight

			// If the scrolling region has changed, attempt to pan the existing text so that it is
			// not overwritten by the table.
			if scrollingHeight < oldScrollingHeight {
				pan := oldScrollingHeight - scrollingHeight
				if pan > s.tableHeight {
					pan = s.tableHeight
				}
				fmt.Fprint(s.writer, ansi.panDown(pan))
			}
		}
	}
}

func (s *smartStatusOutput) actionTable() {
	scrollingHeight := s.termHeight - s.tableHeight

	// Update the scrolling region in case the height of the terminal changed

	fmt.Fprint(s.writer, ansi.setScrollingMargins(1, scrollingHeight))

	// Write as many status lines as fit in the table
	for tableLine := 0; tableLine < s.tableHeight; tableLine++ {
		if tableLine >= s.tableHeight {
			break
		}
		// Move the cursor to the correct line of the non-scrolling region
		fmt.Fprint(s.writer, ansi.setCursor(scrollingHeight+1+tableLine, 1))

		if tableLine < len(s.runningActions) {
			runningAction := s.runningActions[tableLine]

			seconds := int(time.Since(runningAction.startTime).Round(time.Second).Seconds())

			desc := runningAction.action.Description
			if desc == "" {
				desc = runningAction.action.Command
			}

			color := ""
			if seconds >= 60 {
				color = ansi.red() + ansi.bold()
			} else if seconds >= 30 {
				color = ansi.yellow() + ansi.bold()
			}

			durationStr := fmt.Sprintf("   %2d:%02d ", seconds/60, seconds%60)
			desc = elide(desc, s.termWidth-len(durationStr))
			durationStr = color + durationStr + ansi.regular()
			fmt.Fprint(s.writer, durationStr, desc)
		}
		fmt.Fprint(s.writer, ansi.clearToEndOfLine())
	}

	// Move the cursor back to the last line of the scrolling region
	fmt.Fprint(s.writer, ansi.setCursor(scrollingHeight, 1))
}

var ansi = ansiImpl{}

type ansiImpl struct{}

func (ansiImpl) clearToEndOfLine() string {
	return "\x1b[K"
}

func (ansiImpl) setCursor(row, column int) string {
	// Direct cursor address
	return fmt.Sprintf("\x1b[%d;%dH", row, column)
}

func (ansiImpl) setScrollingMargins(top, bottom int) string {
	// Set Top and Bottom Margins DECSTBM
	return fmt.Sprintf("\x1b[%d;%dr", top, bottom)
}

func (ansiImpl) resetScrollingMargins() string {
	// Set Top and Bottom Margins DECSTBM
	return fmt.Sprintf("\x1b[r")
}

func (ansiImpl) red() string {
	return "\x1b[31m"
}

func (ansiImpl) yellow() string {
	return "\x1b[33m"
}

func (ansiImpl) bold() string {
	return "\x1b[1m"
}

func (ansiImpl) regular() string {
	return "\x1b[0m"
}

func (ansiImpl) showCursor() string {
	return "\x1b[?25h"
}

func (ansiImpl) hideCursor() string {
	return "\x1b[?25l"
}

func (ansiImpl) panDown(lines int) string {
	return fmt.Sprintf("\x1b[%dS", lines)
}

func (ansiImpl) panUp(lines int) string {
	return fmt.Sprintf("\x1b[%dT", lines)
}
