// Copyright 2020 Google Inc. All rights reserved.
//
// 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 android

import (
	"bytes"
	"encoding/gob"
	"errors"
	"fmt"
)

// DepSet is designed to be conceptually compatible with Bazel's depsets:
// https://docs.bazel.build/versions/master/skylark/depsets.html

type DepSetOrder int

const (
	PREORDER DepSetOrder = iota
	POSTORDER
	TOPOLOGICAL
)

func (o DepSetOrder) String() string {
	switch o {
	case PREORDER:
		return "PREORDER"
	case POSTORDER:
		return "POSTORDER"
	case TOPOLOGICAL:
		return "TOPOLOGICAL"
	default:
		panic(fmt.Errorf("Invalid DepSetOrder %d", o))
	}
}

type depSettableType comparable

// A DepSet efficiently stores a slice of an arbitrary type from transitive dependencies without
// copying. It is stored as a DAG of DepSet nodes, each of which has some direct contents and a list
// of dependency DepSet nodes.
//
// A DepSet has an order that will be used to walk the DAG when ToList() is called.  The order
// can be POSTORDER, PREORDER, or TOPOLOGICAL.  POSTORDER and PREORDER orders return a postordered
// or preordered left to right flattened list.  TOPOLOGICAL returns a list that guarantees that
// elements of children are listed after all of their parents (unless there are duplicate direct
// elements in the DepSet or any of its transitive dependencies, in which case the ordering of the
// duplicated element is not guaranteed).
//
// A DepSet is created by NewDepSet or NewDepSetBuilder.Build from the slice for direct contents
// and the *DepSets of dependencies. A DepSet is immutable once created.
type DepSet[T depSettableType] struct {
	preorder   bool
	reverse    bool
	order      DepSetOrder
	direct     []T
	transitive []*DepSet[T]
}

func (d *DepSet[T]) GobEncode() ([]byte, error) {
	w := new(bytes.Buffer)
	encoder := gob.NewEncoder(w)
	err := errors.Join(encoder.Encode(d.preorder), encoder.Encode(d.reverse),
		encoder.Encode(d.order), encoder.Encode(d.direct), encoder.Encode(d.transitive))
	if err != nil {
		return nil, err
	}

	return w.Bytes(), nil
}

func (d *DepSet[T]) GobDecode(data []byte) error {
	r := bytes.NewBuffer(data)
	decoder := gob.NewDecoder(r)
	err := errors.Join(decoder.Decode(&d.preorder), decoder.Decode(&d.reverse),
		decoder.Decode(&d.order), decoder.Decode(&d.direct), decoder.Decode(&d.transitive))
	if err != nil {
		return err
	}

	return nil
}

// NewDepSet returns an immutable DepSet with the given order, direct and transitive contents.
func NewDepSet[T depSettableType](order DepSetOrder, direct []T, transitive []*DepSet[T]) *DepSet[T] {
	var directCopy []T
	var transitiveCopy []*DepSet[T]
	for _, t := range transitive {
		if t.order != order {
			panic(fmt.Errorf("incompatible order, new DepSet is %s but transitive DepSet is %s",
				order, t.order))
		}
	}

	if order == TOPOLOGICAL {
		// TOPOLOGICAL is implemented as a postorder traversal followed by reversing the output.
		// Pre-reverse the inputs here so their order is maintained in the output.
		directCopy = ReverseSlice(direct)
		transitiveCopy = ReverseSlice(transitive)
	} else {
		directCopy = append([]T(nil), direct...)
		transitiveCopy = append([]*DepSet[T](nil), transitive...)
	}

	return &DepSet[T]{
		preorder:   order == PREORDER,
		reverse:    order == TOPOLOGICAL,
		order:      order,
		direct:     directCopy,
		transitive: transitiveCopy,
	}
}

// DepSetBuilder is used to create an immutable DepSet.
type DepSetBuilder[T depSettableType] struct {
	order      DepSetOrder
	direct     []T
	transitive []*DepSet[T]
}

// NewDepSetBuilder returns a DepSetBuilder to create an immutable DepSet with the given order and
// type, represented by a slice of type that will be in the DepSet.
func NewDepSetBuilder[T depSettableType](order DepSetOrder) *DepSetBuilder[T] {
	return &DepSetBuilder[T]{
		order: order,
	}
}

// DirectSlice adds direct contents to the DepSet being built by a DepSetBuilder. Newly added direct
// contents are to the right of any existing direct contents.
func (b *DepSetBuilder[T]) DirectSlice(direct []T) *DepSetBuilder[T] {
	b.direct = append(b.direct, direct...)
	return b
}

// Direct adds direct contents to the DepSet being built by a DepSetBuilder. Newly added direct
// contents are to the right of any existing direct contents.
func (b *DepSetBuilder[T]) Direct(direct ...T) *DepSetBuilder[T] {
	b.direct = append(b.direct, direct...)
	return b
}

// Transitive adds transitive contents to the DepSet being built by a DepSetBuilder. Newly added
// transitive contents are to the right of any existing transitive contents.
func (b *DepSetBuilder[T]) Transitive(transitive ...*DepSet[T]) *DepSetBuilder[T] {
	for _, t := range transitive {
		if t.order != b.order {
			panic(fmt.Errorf("incompatible order, new DepSet is %s but transitive DepSet is %s",
				b.order, t.order))
		}
	}
	b.transitive = append(b.transitive, transitive...)
	return b
}

// Returns the DepSet being built by this DepSetBuilder.  The DepSetBuilder retains its contents
// for creating more depSets.
func (b *DepSetBuilder[T]) Build() *DepSet[T] {
	return NewDepSet(b.order, b.direct, b.transitive)
}

// walk calls the visit method in depth-first order on a DepSet, preordered if d.preorder is set,
// otherwise postordered.
func (d *DepSet[T]) walk(visit func([]T)) {
	visited := make(map[*DepSet[T]]bool)

	var dfs func(d *DepSet[T])
	dfs = func(d *DepSet[T]) {
		visited[d] = true
		if d.preorder {
			visit(d.direct)
		}
		for _, dep := range d.transitive {
			if !visited[dep] {
				dfs(dep)
			}
		}

		if !d.preorder {
			visit(d.direct)
		}
	}

	dfs(d)
}

// ToList returns the DepSet flattened to a list.  The order in the list is based on the order
// of the DepSet.  POSTORDER and PREORDER orders return a postordered or preordered left to right
// flattened list.  TOPOLOGICAL returns a list that guarantees that elements of children are listed
// after all of their parents (unless there are duplicate direct elements in the DepSet or any of
// its transitive dependencies, in which case the ordering of the duplicated element is not
// guaranteed).
func (d *DepSet[T]) ToList() []T {
	if d == nil {
		return nil
	}
	var list []T
	d.walk(func(paths []T) {
		list = append(list, paths...)
	})
	list = firstUniqueInPlace(list)
	if d.reverse {
		ReverseSliceInPlace(list)
	}
	return list
}
