// 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))
	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
}
