// Copyright 2018 The 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 trim removes fields that may be inferred from another mixed in value
// that "dominates" it. For instance, a value that is merged in from a
// definition is considered to dominate a value from a regular struct that
// mixes in this definition. Values derived from constraints and comprehensions
// can also dominate other fields.
//
// A value A is considered to be implied by a value B if A subsumes the default
// value of B. For instance, if a definition defines a field `a: *1 | int` and
// mixed in with a struct that defines a field `a: 1 | 2`, then the latter can
// be removed because a definition field dominates a regular field and because
// the latter subsumes the default value of the former.
//
//
// Examples:
//
// 	light: [string]: {
// 		room:          string
// 		brightnessOff: *0.0 | >=0 & <=100.0
// 		brightnessOn:  *100.0 | >=0 & <=100.0
// 	}
//
// 	light: ceiling50: {
// 		room:          "MasterBedroom"
// 		brightnessOff: 0.0    // this line
// 		brightnessOn:  100.0  // and this line will be removed
// 	}
//
// Results in:
//
// 	// Unmodified: light: [string]: { ... }
//
// 	light: ceiling50: {
// 		room: "MasterBedroom"
// 	}
//
package trim

import (
	"cuelang.org/go/cue"
	"cuelang.org/go/cue/ast"
	"cuelang.org/go/cue/ast/astutil"
	"cuelang.org/go/internal"
	"cuelang.org/go/internal/core/adt"
	"cuelang.org/go/internal/core/runtime"
	"cuelang.org/go/internal/core/subsume"
)

// Config configures trim options.
type Config struct {
	Trace bool
}

// Files trims fields in the given files that can be implied from other fields,
// as can be derived from the evaluated values in inst.
// Trimming is done on a best-effort basis and only when the removed field
// is clearly implied by another field, rather than equal sibling fields.
func Files(files []*ast.File, inst *cue.Instance, cfg *Config) error {
	rx, vx := internal.CoreValue(inst.Value())
	r := rx.(*runtime.Runtime)
	v := vx.(*adt.Vertex)

	t := &trimmer{
		Config: *cfg,
		ctx:    adt.NewContext(r, v),
		remove: map[ast.Node]bool{},
	}

	t.findSubordinates(v)

	// Remove subordinate values from files.
	for _, f := range files {
		astutil.Apply(f, func(c astutil.Cursor) bool {
			if f, ok := c.Node().(*ast.Field); ok && t.remove[f.Value] {
				c.Delete()
			}
			return true
		}, nil)
	}

	return nil
}

type trimmer struct {
	Config

	ctx    *adt.OpContext
	remove map[ast.Node]bool
}

func (t *trimmer) markRemove(c adt.Conjunct) {
	if src := c.Expr().Source(); src != nil {
		t.remove[src] = true
	}
}

const dominatorNode = adt.ComprehensionSpan | adt.DefinitionSpan | adt.ConstraintSpan

func isDominator(c adt.Conjunct) bool {
	return c.CloseInfo.IsInOneOf(dominatorNode)
}

// Roots of constraints are not allowed to strip conjuncts by
// themselves as it will eliminate the reason for the trigger.
func allowRemove(v *adt.Vertex) bool {
	for _, c := range v.Conjuncts {
		if isDominator(c) &&
			(c.CloseInfo.Location() != c.Expr() ||
				c.CloseInfo.RootSpanType() != adt.ConstraintSpan) {
			return true
		}
	}
	return false
}

// A parent may be removed if there is not a `no` and there is at least one
// `yes`. A `yes` is proves that there is at least one node that is not a
// dominator node and that we are not removing nodes from a declaration of a
// dominator itself.
const (
	no = 1 << iota
	maybe
	yes
)

func (t *trimmer) findSubordinates(v *adt.Vertex) int {
	// TODO(structure sharing): do not descend into vertices whose parent is not
	// equal to the parent. This is not relevant at this time, but may be so in
	// the future.

	if len(v.Arcs) > 0 {
		var match int
		for _, a := range v.Arcs {
			match |= t.findSubordinates(a)
		}

		// This also skips embedded scalars if not all fields are removed. In
		// this case we need to preserve the scalar to keep the type of the
		// struct intact, which might as well be done by not removing the scalar
		// type.
		if match&yes == 0 || match&no != 0 {
			return match
		}
	}

	if !allowRemove(v) {
		return no
	}

	switch v.BaseValue.(type) {
	case *adt.StructMarker, *adt.ListMarker:
		// Rely on previous processing of the Arcs and the fact that we take the
		// default value to check dominator subsumption, meaning that we don't
		// have to check additional optional constraints to pass subsumption.

	default:
		doms := &adt.Vertex{}
		hasSubs := false

		for _, c := range v.Conjuncts {
			if isDominator(c) {
				doms.AddConjunct(c)
			} else {
				hasSubs = true
			}
		}

		if !hasSubs {
			return maybe // only if there are siblings to be removed.
		}

		doms.Finalize(t.ctx)
		doms = doms.Default()

		// This is not necessary, but seems like it may result in more
		// user-friendly semantics.
		if doms.IsErr() || v.IsErr() {
			return no
		}

		// TODO: since we take v, instead of the unification of subordinate
		// values, it should suffice to take equality here:
		//    doms ⊑ subs  ==> doms == subs&doms
		if err := subsume.Value(t.ctx, v, doms); err != nil {
			return no
		}
	}

	for _, c := range v.Conjuncts {
		if !isDominator(c) {
			t.markRemove(c)
		}
	}

	return yes
}
