// Copyright 2021 Google LLC
//
// 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 compliance

import (
	"fmt"
	"strings"
)

// ResolutionSet describes an immutable set of targets and the license
// conditions each target must satisfy or "resolve" in a specific context.
//
// Ultimately, the purpose of recording the license metadata and building a
// license graph is to identify, describe, and verify the necessary actions or
// operations for compliance policy.
//
// i.e. What is the source-sharing policy? Has it been met? Meet it.
//
// i.e. Are there incompatible policy requirements? Such as a source-sharing
// policy applied to code that policy also says may not be shared? If so, stop
// and remove the dependencies that create the situation.
//
// The ResolutionSet is the base unit for mapping license conditions to the
// targets triggering some necessary action per policy. Different ResolutionSet
// values may be calculated for different contexts.
//
// e.g. Suppose an unencumbered binary links in a notice .a library.
//
// An "unencumbered" condition would originate from the binary, and a "notice"
// condition would originate from the .a library. A ResolutionSet for the
// context of the Notice policy might attach both conditions to the binary to
// act on the origin of each condition. By attaching the notice condition to
// the binary, the ResolutionSet stipulates the policy that the release of the
// unencumbered binary must provide suitable notice for the .a library.
//
// The resulting ResolutionSet could be used for building a notice file, for
// validating that a suitable notice has been built into the distribution, or
// for reporting what notices need to be given.
//
// The action is defined by the context. In the above example, the action is
// providing notice for the module acted on. In another context, the action
// might be sharing the source-code or preserving the privacy of the module
// acted on.
type ResolutionSet map[*TargetNode]ActionSet

// AttachesTo identifies the list of targets triggering action to resolve
// conditions. (unordered)
func (rs ResolutionSet) AttachesTo() TargetNodeList {
	result := make(TargetNodeList, 0, len(rs))
	for attachesTo := range rs {
		result = append(result, attachesTo)
	}
	return result
}

// AttachesToTarget returns true if the set contains conditions that
// are `attachedTo`.
func (rs ResolutionSet) AttachesToTarget(target *TargetNode) bool {
	_, isPresent := rs[target]
	return isPresent
}

// Resolutions returns the list of resolutions that `attachedTo`
// target must resolve. Returns empty list if no conditions apply.
func (rs ResolutionSet) Resolutions(attachesTo *TargetNode) ResolutionList {
	as, ok := rs[attachesTo]
	if !ok {
		return nil
	}
	result := make(ResolutionList, 0, len(as))
	for actsOn, cs := range as {
		result = append(result, Resolution{attachesTo, actsOn, cs})
	}
	return result
}

// AllActions returns the set of actions required to resolve the set omitting
// the attachment.
func (rs ResolutionSet) AllActions() ActionSet {
	result := make(ActionSet)
	for _, as := range rs {
		for actsOn, cs := range as {
			if _, ok := result[actsOn]; ok {
				result[actsOn] = cs.Union(result[actsOn])
			} else {
				result[actsOn] = cs
			}
		}
	}
	return result
}

// String returns a human-readable string representation of the set.
func (rs ResolutionSet) String() string {
	var sb strings.Builder
	fmt.Fprintf(&sb, "{")
	sep := ""
	for attachesTo, as := range rs {
		fmt.Fprintf(&sb, "%s%s -> %s", sep, attachesTo.Name(), as.String())
		sep = ", "
	}
	fmt.Fprintf(&sb, "}")
	return sb.String()
}

// ActionSet identifies a set of targets to act on and the license conditions
// the action will resolve.
type ActionSet map[*TargetNode]LicenseConditionSet

// String returns a human-readable string representation of the set.
func (as ActionSet) String() string {
	var sb strings.Builder
	fmt.Fprintf(&sb, "{")
	sep := ""
	for actsOn, cs := range as {
		fmt.Fprintf(&sb, "%s%s%s", sep, actsOn.Name(), cs.String())
		sep = ", "
	}
	fmt.Fprintf(&sb, "}")
	return sb.String()
}
