// Copyright 2023 The Tint 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 build

import (
	"sort"

	"dawn.googlesource.com/dawn/tools/src/container"
	"dawn.googlesource.com/dawn/tools/src/transform"
)

// Directory holds information about a build target
type Target struct {
	// The target's name
	Name TargetName
	// The kind of target
	Kind TargetKind
	// The directory holding the target
	Directory *Directory
	// All project-relative paths of source files that are part of this target
	SourceFileSet container.Set[string]
	// Dependencies of this target
	Dependencies *Dependencies
	// An optional custom output name for the target
	OutputName string
	// An optional condition for building this target
	Condition string
}

// AddSourceFile adds the File to the target's source set
func (t *Target) AddSourceFile(f *File) {
	t.SourceFileSet.Add(f.Path())
	f.Target = t
}

// SourceFiles returns the sorted list of the target's source files
func (t *Target) SourceFiles() []*File {
	out := make([]*File, len(t.SourceFileSet))
	for i, name := range t.SourceFileSet.List() {
		out[i] = t.Directory.Project.Files[name]
	}
	return out
}

// SourceFiles returns the sorted list of the target's source files that have no build condition
func (t *Target) UnconditionalSourceFiles() []*File {
	return transform.Filter(t.SourceFiles(), func(t *File) bool { return t.Condition == "" })
}

// A collection of source files and dependencies sharing the same condition
type TargetConditional struct {
	Condition            string
	SourceFiles          []*File
	InternalDependencies []*Target
	ExternalDependencies []ExternalDependency
}

// A collection of source files and dependencies sharing the same condition
type TargetConditionals []*TargetConditional

// HasSourceFiles returns true if any of the conditionals in l have source files
func (l TargetConditionals) HasSourceFiles() bool {
	for _, c := range l {
		if len(c.SourceFiles) > 0 {
			return true
		}
	}
	return false
}

// HasDependencies returns true if any of the conditionals in l have internal or external dependencies
func (l TargetConditionals) HasDependencies() bool {
	for _, c := range l {
		if len(c.InternalDependencies) > 0 || len(c.ExternalDependencies) > 0 {
			return true
		}
	}
	return false
}

// Conditionals returns a sorted list of TargetConditional, which are grouped by condition
func (t *Target) Conditionals() TargetConditionals {
	m := container.NewMap[string, *TargetConditional]()
	for name := range t.SourceFileSet {
		file := t.Directory.Project.Files[name]
		if file.Condition != "" {
			c := m.GetOrCreate(file.Condition, func() *TargetConditional {
				return &TargetConditional{Condition: file.Condition}
			})
			c.SourceFiles = append(c.SourceFiles, file)
		}
	}
	for name := range t.Dependencies.internal {
		dep := t.Directory.Project.Targets[name]
		if dep.Condition != "" {
			c := m.GetOrCreate(dep.Condition, func() *TargetConditional {
				return &TargetConditional{Condition: dep.Condition}
			})
			c.InternalDependencies = append(c.InternalDependencies, dep)
		}
	}
	for name := range t.Dependencies.external {
		dep := t.Directory.Project.externals[name]
		if dep.Condition != "" {
			c := m.GetOrCreate(dep.Condition, func() *TargetConditional {
				return &TargetConditional{Condition: dep.Condition}
			})
			c.ExternalDependencies = append(c.ExternalDependencies, dep)
		}
	}
	for _, c := range m {
		sort.Slice(c.SourceFiles, func(a, b int) bool { return c.SourceFiles[a].Name < c.SourceFiles[b].Name })
		sort.Slice(c.InternalDependencies, func(a, b int) bool { return c.InternalDependencies[a].Name < c.InternalDependencies[b].Name })
		sort.Slice(c.ExternalDependencies, func(a, b int) bool { return c.ExternalDependencies[a].Name < c.ExternalDependencies[b].Name })
	}
	return TargetConditionals(m.Values())
}
