// Copyright 2020 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 subsume defines various subsumption relations.
package subsume

import (
	"cuelang.org/go/cue/errors"
	"cuelang.org/go/internal"
	"cuelang.org/go/internal/core/adt"
)

// Profile configures the type of subsumption. One should typically use one
// of the preconfigured profiles.
type Profile struct {
	// Final indicates subsumption should only consider fields that are relevant
	// to data mode, and ignore definitions, hidden fields, pattern constraints
	// and additional constraints.
	Final bool

	// Defaults indicate that default values should be used for the subsumed
	// value.
	Defaults bool

	// Ignore optional fields.
	IgnoreOptional bool

	// IgnoreClosedness ignores closedness of structs and is used for comparing
	// APIs.
	IgnoreClosedness bool
}

var CUE = Profile{}

// Final checks subsumption interpreting the subsumed value as data.
var Final = Profile{
	Final:    true,
	Defaults: true,
}

// FinalOpen exists as an artifact of the old API. One should probably not use
// this.
var FinalOpen = Profile{
	Final:            true,
	Defaults:         true,
	IgnoreClosedness: true,
}

// API is subsumption used for APIs.
var API = Profile{
	IgnoreClosedness: true,
}

// Value subsumes two values based on their logical (evaluated) values.
func Value(ctx *adt.OpContext, a, b adt.Value) errors.Error {
	return CUE.Value(ctx, a, b)
}

func (p *Profile) Value(ctx *adt.OpContext, a, b adt.Value) errors.Error {
	s := subsumer{ctx: ctx, Profile: *p}
	if !s.values(a, b) {
		return s.getError()
	}
	return nil // ignore errors here even if there are some.
}

// Check reports whether b is an instance of a.
func (p *Profile) Check(ctx *adt.OpContext, a, b adt.Value) bool {
	s := subsumer{ctx: ctx, Profile: *p}
	return s.values(a, b)
}

func isBottom(x adt.Node) bool {
	b, _ := x.(*adt.Bottom)
	return b != nil
}

type subsumer struct {
	ctx  *adt.OpContext
	errs errors.Error

	Profile

	inexact bool // If true, the result could be a false negative.
	missing adt.Feature
	gt      adt.Value
	lt      adt.Value
}

func (s *subsumer) errf(msg string, args ...interface{}) {
	b := s.ctx.NewErrf(msg, args...)
	s.errs = errors.Append(s.errs, b.Err)
}

func unifyValue(c *adt.OpContext, a, b adt.Value) adt.Value {
	v := &adt.Vertex{}
	v.AddConjunct(adt.MakeRootConjunct(c.Env(0), a))
	v.AddConjunct(adt.MakeRootConjunct(c.Env(0), b))
	x, _ := c.Evaluate(c.Env(0), v)
	return x
}

func (s *subsumer) getError() (err errors.Error) {
	c := s.ctx
	// src := binSrc(token.NoPos, opUnify, gt, lt)
	if s.gt != nil && s.lt != nil {
		// src := binSrc(token.NoPos, opUnify, s.gt, s.lt)
		if s.missing != 0 {
			s.errf("missing field %q", s.missing.SelectorString(c))
		} else if b, ok := unifyValue(c, s.gt, s.lt).(*adt.Bottom); !ok {
			s.errf("value not an instance")
		} else {
			s.errs = errors.Append(s.errs, b.Err)
		}
	}
	if s.errs == nil {
		s.errf("value not an instance")
	}
	err = s.errs
	if s.inexact {
		err = internal.DecorateError(internal.ErrInexact, err)
	}
	return err
}
