// 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 s.errs
}

// 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))
	return c.Unifier.Evaluate(c, v)
}

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
}
