// Copyright 2019 CUE 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 os

//go:generate go run gen.go

import (
	"fmt"
	"os"
	"strings"

	"cuelang.org/go/cue"
	"cuelang.org/go/cue/ast"
	"cuelang.org/go/cue/errors"
	"cuelang.org/go/internal/cli"
	"cuelang.org/go/internal/task"
)

func init() {
	task.Register("tool/os.Setenv", newSetenvCmd)
	task.Register("tool/os.Getenv", newGetenvCmd)
	task.Register("tool/os.Environ", newEnvironCmd)
	task.Register("tool/os.Clearenv", newClearenvCmd)

	// TODO:
	// Tasks:
	// - Exit?
	// - Getwd/ Setwd (or in tool/file?)

	// Functions:
	// - Hostname
	// - UserCache/Home/Config (or in os/user?)
}

type clearenvCmd struct{}

func newClearenvCmd(v cue.Value) (task.Runner, error) {
	return &clearenvCmd{}, nil
}

func (c *clearenvCmd) Run(ctx *task.Context) (res interface{}, err error) {
	os.Clearenv()
	return map[string]interface{}{}, nil
}

type setenvCmd struct{}

func newSetenvCmd(v cue.Value) (task.Runner, error) {
	return &setenvCmd{}, nil
}

func (c *setenvCmd) Run(ctx *task.Context) (res interface{}, err error) {
	iter, err := ctx.Obj.Fields()
	if err != nil {
		return nil, err
	}

	for iter.Next() {
		name := iter.Label()
		if strings.HasPrefix(name, "$") {
			continue
		}

		v, _ := iter.Value().Default()

		if !v.IsConcrete() {
			return nil, errors.Newf(v.Pos(),
				"non-concrete environment variable %s", name)
		}
		switch k := v.IncompleteKind(); k {
		case cue.ListKind, cue.StructKind:
			return nil, errors.Newf(v.Pos(),
				"unsupported type %s for environment variable %s", k, name)

		case cue.NullKind:
			err = os.Unsetenv(name)

		case cue.BoolKind:
			if b, _ := v.Bool(); b {
				err = os.Setenv(name, "1")
			} else {
				err = os.Setenv(name, "0")
			}

		case cue.StringKind:
			s, _ := v.String()
			err = os.Setenv(name, s)

		default:
			err = os.Setenv(name, fmt.Sprint(v))
		}

		if err != nil {
			return nil, err
		}
	}

	return map[string]interface{}{}, err
}

type getenvCmd struct{}

func newGetenvCmd(v cue.Value) (task.Runner, error) {
	return &getenvCmd{}, nil
}

func (c *getenvCmd) Run(ctx *task.Context) (res interface{}, err error) {
	iter, err := ctx.Obj.Fields()
	if err != nil {
		return nil, err
	}

	update := map[string]interface{}{}

	for iter.Next() {
		name := iter.Label()
		if strings.HasPrefix(name, "$") {
			continue
		}
		v := iter.Value()

		if err := validateEntry(name, v); err != nil {
			return nil, err
		}

		str, ok := os.LookupEnv(name)
		if !ok {
			update[name] = nil
			continue
		}
		x, err := fromString(name, str, v)
		if err != nil {
			return nil, err
		}
		update[name] = x
	}

	return update, nil
}

type environCmd struct{}

func newEnvironCmd(v cue.Value) (task.Runner, error) {
	return &environCmd{}, nil
}

func (c *environCmd) Run(ctx *task.Context) (res interface{}, err error) {
	iter, err := ctx.Obj.Fields()
	if err != nil {
		return nil, err
	}

	update := map[string]interface{}{}

	for _, kv := range os.Environ() {
		a := strings.SplitN(kv, "=", 2)

		name := a[0]
		str := a[1]

		if v := ctx.Obj.Lookup(name); v.Exists() {
			update[name], err = fromString(name, str, v)
			if err != nil {
				return nil, err
			}
		} else {
			update[name] = str
		}
	}

	for iter.Next() {
		name := iter.Label()
		if strings.HasPrefix(name, "$") {
			continue
		}
		if err := validateEntry(name, iter.Value()); err != nil {
			return nil, err
		}
		if _, ok := update[name]; !ok {
			update[name] = nil
		}
	}

	return update, nil
}

func validateEntry(name string, v cue.Value) error {
	if k := v.IncompleteKind(); k&^(cue.NumberKind|cue.NullKind|cue.BoolKind|cue.StringKind) != 0 {
		return errors.Newf(v.Pos(),
			"invalid type %s for environment variable %s", k, name)
	}
	return nil
}

func fromString(name, str string, v cue.Value) (x ast.Node, err error) {
	k := v.IncompleteKind()
	return cli.ParseValue(v.Pos(), name, str, k)
}
