// goredo -- djb's redo implementation on pure Go
// Copyright (C) 2020-2026 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 3 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

package main

import (
	"flag"
	"fmt"
	"log"
	"os"
)

const (
	EnvStatusFd = "REDO_STATUS_FD"
	EnvNoStatus = "REDO_NO_STATUS"

	StatusRun = iota
	StatusDone
	StatusWait
	StatusWaited
)

var (
	FdStatus *os.File

	flagNoStatus *bool
)

func init() {
	cmdName := CmdName()
	if !(cmdName == CmdNameRedo || cmdName == CmdNameRedoIfchange) {
		return
	}
	flagNoStatus = flag.Bool("no-status", false, "disable statusline (REDO_NO_STATUS=1)")
}

func statusInit() {
	if NoProgress || *flagNoStatus {
		return
	}
	if v := os.Getenv(EnvNoStatus); v == "1" {
		return
	}
	if v := os.Getenv(EnvStatusFd); v != "" {
		if v == "NO" {
			return
		}
		FdStatus = mustParseFd(v, EnvStatusFd)
		return
	}
	var r *os.File
	var err error
	r, FdStatus, err = os.Pipe()
	if err != nil {
		log.Fatal(err)
	}
	go func() {
		running := 0
		waiting := 0
		done := 0
		var out string
		buf := make([]byte, 1)
		var n int
		for {
			n, err = r.Read(buf)
			if err != nil || n != 1 {
				break
			}
			switch buf[0] {
			case StatusRun:
				running++
			case StatusDone:
				running--
				done++
			case StatusWait:
				waiting++
			case StatusWaited:
				waiting--
			}
			if NoColor {
				out = fmt.Sprintf(
					"\rrun: %d wait: %d done: %d",
					running, waiting, done,
				)
			} else {
				out = fmt.Sprintf(
					"\rrun: %s%d%s wait: %s%d%s done: %s%d%s",
					CRedo, running, CReset,
					CWait, waiting, CReset,
					CJS, done, CReset,
				)
			}
			out = erasedStatus(out, "\r")
			LogMutex.Lock()
			os.Stderr.WriteString(out)
			LogMutex.Unlock()
		}
	}()
}
