// 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 (
	"path"
	"path/filepath"
	"sync"
)

var (
	TgtCache  = make(map[string]*Tgt)
	TgtCacheM sync.RWMutex
)

func mustAbs(pth string) string {
	pth, err := filepath.Abs(pth)
	if err != nil {
		panic(err)
	}
	return pth
}

func mustRel(basepath, targpath string) string {
	pth, err := filepath.Rel(basepath, targpath)
	if err != nil {
		panic(err)
	}
	return pth
}

func cwdMustRel(paths ...string) string {
	return mustRel(Cwd, path.Join(paths...))
}

func pathSplit(a string) (h, t string) {
	h, t = path.Split(a)
	if len(h) > 1 {
		h = h[:len(h)-1]
	}
	return
}

type Tgt struct {
	a   string // absolute path
	rel string // relative to Cwd
	dep string // path to dependency file
}

func NewTgt(tgt string) *Tgt {
	a := mustAbs(tgt)
	TgtCacheM.RLock()
	cached := TgtCache[a]
	TgtCacheM.RUnlock()
	if cached != nil {
		return cached
	}
	h, t := pathSplit(a)
	res := Tgt{
		a:   a,
		rel: mustRel(Cwd, a),
		dep: path.Join(h, RedoDir, t+DepSuffix),
	}
	TgtCacheM.Lock()
	TgtCache[a] = &res
	TgtCacheM.Unlock()
	return &res
}

func (tgt *Tgt) String() string {
	return tgt.rel
}

func (tgt *Tgt) RelTo(cwd string) string {
	return mustRel(cwd, tgt.a)
}
