// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package script

import (
	"cmd/go/internal/imports"
	"fmt"
	"os"
	"runtime"
	"sync"
)

// DefaultConds returns a set of broadly useful script conditions.
//
// Run the 'help' command within a script engine to view a list of the available
// conditions.
func DefaultConds() map[string]Cond {
	conds := make(map[string]Cond)

	conds["GOOS"] = PrefixCondition(
		"runtime.GOOS == <suffix>",
		func(_ *State, suffix string) (bool, error) {
			if suffix == runtime.GOOS {
				return true, nil
			}
			if _, ok := imports.KnownOS[suffix]; !ok {
				return false, fmt.Errorf("unrecognized GOOS %q", suffix)
			}
			return false, nil
		})

	conds["GOARCH"] = PrefixCondition(
		"runtime.GOARCH == <suffix>",
		func(_ *State, suffix string) (bool, error) {
			if suffix == runtime.GOARCH {
				return true, nil
			}
			if _, ok := imports.KnownArch[suffix]; !ok {
				return false, fmt.Errorf("unrecognized GOOS %q", suffix)
			}
			return false, nil
		})

	conds["compiler"] = PrefixCondition(
		"runtime.Compiler == <suffix>",
		func(_ *State, suffix string) (bool, error) {
			if suffix == runtime.Compiler {
				return true, nil
			}
			switch suffix {
			case "gc", "gccgo":
				return false, nil
			default:
				return false, fmt.Errorf("unrecognized compiler %q", suffix)
			}
		})

	conds["root"] = BoolCondition("os.Geteuid() == 0", os.Geteuid() == 0)

	return conds
}

// Condition returns a Cond with the given summary and evaluation function.
func Condition(summary string, eval func(*State) (bool, error)) Cond {
	return &funcCond{eval: eval, usage: CondUsage{Summary: summary}}
}

type funcCond struct {
	eval  func(*State) (bool, error)
	usage CondUsage
}

func (c *funcCond) Usage() *CondUsage { return &c.usage }

func (c *funcCond) Eval(s *State, suffix string) (bool, error) {
	if suffix != "" {
		return false, ErrUsage
	}
	return c.eval(s)
}

// PrefixCondition returns a Cond with the given summary and evaluation function.
func PrefixCondition(summary string, eval func(*State, string) (bool, error)) Cond {
	return &prefixCond{eval: eval, usage: CondUsage{Summary: summary, Prefix: true}}
}

type prefixCond struct {
	eval  func(*State, string) (bool, error)
	usage CondUsage
}

func (c *prefixCond) Usage() *CondUsage { return &c.usage }

func (c *prefixCond) Eval(s *State, suffix string) (bool, error) {
	return c.eval(s, suffix)
}

// BoolCondition returns a Cond with the given truth value and summary.
// The Cond rejects the use of condition suffixes.
func BoolCondition(summary string, v bool) Cond {
	return &boolCond{v: v, usage: CondUsage{Summary: summary}}
}

type boolCond struct {
	v     bool
	usage CondUsage
}

func (b *boolCond) Usage() *CondUsage { return &b.usage }

func (b *boolCond) Eval(s *State, suffix string) (bool, error) {
	if suffix != "" {
		return false, ErrUsage
	}
	return b.v, nil
}

// OnceCondition returns a Cond that calls eval the first time the condition is
// evaluated. Future calls reuse the same result.
//
// The eval function is not passed a *State because the condition is cached
// across all execution states and must not vary by state.
func OnceCondition(summary string, eval func() (bool, error)) Cond {
	return &onceCond{eval: eval, usage: CondUsage{Summary: summary}}
}

type onceCond struct {
	once  sync.Once
	v     bool
	err   error
	eval  func() (bool, error)
	usage CondUsage
}

func (l *onceCond) Usage() *CondUsage { return &l.usage }

func (l *onceCond) Eval(s *State, suffix string) (bool, error) {
	if suffix != "" {
		return false, ErrUsage
	}
	l.once.Do(func() { l.v, l.err = l.eval() })
	return l.v, l.err
}

// CachedCondition is like Condition but only calls eval the first time the
// condition is evaluated for a given suffix.
// Future calls with the same suffix reuse the earlier result.
//
// The eval function is not passed a *State because the condition is cached
// across all execution states and must not vary by state.
func CachedCondition(summary string, eval func(string) (bool, error)) Cond {
	return &cachedCond{eval: eval, usage: CondUsage{Summary: summary, Prefix: true}}
}

type cachedCond struct {
	m     sync.Map
	eval  func(string) (bool, error)
	usage CondUsage
}

func (c *cachedCond) Usage() *CondUsage { return &c.usage }

func (c *cachedCond) Eval(_ *State, suffix string) (bool, error) {
	for {
		var ready chan struct{}

		v, loaded := c.m.Load(suffix)
		if !loaded {
			ready = make(chan struct{})
			v, loaded = c.m.LoadOrStore(suffix, (<-chan struct{})(ready))

			if !loaded {
				inPanic := true
				defer func() {
					if inPanic {
						c.m.Delete(suffix)
					}
					close(ready)
				}()

				b, err := c.eval(suffix)
				inPanic = false

				if err == nil {
					c.m.Store(suffix, b)
					return b, nil
				} else {
					c.m.Store(suffix, err)
					return false, err
				}
			}
		}

		switch v := v.(type) {
		case bool:
			return v, nil
		case error:
			return false, v
		case <-chan struct{}:
			<-v
		}
	}
}
