package bpdoc

import (
	"fmt"
	"html/template"
	"reflect"
	"sort"
	"strings"

	"github.com/google/blueprint/proptools"
)

// Package contains the information about a package relevant to generating documentation.
type Package struct {
	// Name is the name of the package.
	Name string

	// Path is the full package path of the package as used in the primary builder.
	Path string

	// Text is the contents of the package comment documenting the module types in the package.
	Text string

	// ModuleTypes is a list of ModuleType objects that contain information about each module type that is
	// defined by the package.
	ModuleTypes []*ModuleType
}

// ModuleType contains the information about a module type that is relevant to generating documentation.
type ModuleType struct {
	// Name is the string that will appear in Blueprints files when defining a new module of
	// this type.
	Name string

	// PkgPath is the full package path of the package that contains the module type factory.
	PkgPath string

	// Text is the contents of the comment documenting the module type.
	Text template.HTML

	// PropertyStructs is a list of PropertyStruct objects that contain information about each
	// property struct that is used by the module type, containing all properties that are valid
	// for the module type.
	PropertyStructs []*PropertyStruct
}

type PropertyStruct struct {
	Name       string
	Text       string
	Properties []Property
}

type Property struct {
	Name       string
	OtherNames []string
	Type       string
	Tag        reflect.StructTag
	Text       template.HTML
	OtherTexts []template.HTML
	Properties []Property
	Default    string
	Anonymous  bool
}

func AllPackages(pkgFiles map[string][]string, moduleTypeNameFactories map[string]reflect.Value,
	moduleTypeNamePropertyStructs map[string][]interface{}) ([]*Package, error) {
	// Read basic info from the files to construct a Reader instance.
	r := NewReader(pkgFiles)

	pkgMap := map[string]*Package{}
	var pkgs []*Package
	// Scan through per-module-type property structs map.
	for mtName, propertyStructs := range moduleTypeNamePropertyStructs {
		// Construct ModuleType with the given info.
		mtInfo, err := assembleModuleTypeInfo(r, mtName, moduleTypeNameFactories[mtName], propertyStructs)
		if err != nil {
			return nil, err
		}
		// Some pruning work
		removeAnonymousProperties(mtInfo)
		removeEmptyPropertyStructs(mtInfo)
		collapseDuplicatePropertyStructs(mtInfo)
		collapseNestedPropertyStructs(mtInfo)
		combineDuplicateProperties(mtInfo)

		// Add the ModuleInfo to the corresponding Package map/slice entries.
		pkg := pkgMap[mtInfo.PkgPath]
		if pkg == nil {
			var err error
			pkg, err = r.Package(mtInfo.PkgPath)
			if err != nil {
				return nil, err
			}
			pkgMap[mtInfo.PkgPath] = pkg
			pkgs = append(pkgs, pkg)
		}
		pkg.ModuleTypes = append(pkg.ModuleTypes, mtInfo)
	}

	// Sort ModuleTypes within each package.
	for _, pkg := range pkgs {
		sort.Slice(pkg.ModuleTypes, func(i, j int) bool { return pkg.ModuleTypes[i].Name < pkg.ModuleTypes[j].Name })
	}
	// Sort packages.
	sort.Slice(pkgs, func(i, j int) bool { return pkgs[i].Path < pkgs[j].Path })

	return pkgs, nil
}

func assembleModuleTypeInfo(r *Reader, name string, factory reflect.Value,
	propertyStructs []interface{}) (*ModuleType, error) {

	mt, err := r.ModuleType(name, factory)
	if err != nil {
		return nil, err
	}

	// Reader.ModuleType only fills basic information such as name and package path. Collect more info
	// from property struct data.
	for _, s := range propertyStructs {
		v := reflect.ValueOf(s).Elem()
		t := v.Type()

		// Ignore property structs with unexported or unnamed types
		if t.PkgPath() == "" {
			continue
		}
		ps, err := r.PropertyStruct(t.PkgPath(), t.Name(), v)
		if err != nil {
			return nil, err
		}
		ps.ExcludeByTag("blueprint", "mutated")

		for _, nestedProperty := range nestedPropertyStructs(v) {
			nestedName := nestedProperty.nestPoint
			nestedValue := nestedProperty.value
			nestedType := nestedValue.Type()

			// Ignore property structs with unexported or unnamed types
			if nestedType.PkgPath() == "" {
				continue
			}
			nested, err := r.PropertyStruct(nestedType.PkgPath(), nestedType.Name(), nestedValue)
			if err != nil {
				return nil, err
			}
			nested.ExcludeByTag("blueprint", "mutated")
			if nestedName == "" {
				ps.Nest(nested)
			} else {
				nestPoint := ps.GetByName(nestedName)
				if nestPoint == nil {
					return nil, fmt.Errorf("nesting point %q not found", nestedName)
				}
				nestPoint.Nest(nested)
			}

			if nestedProperty.anonymous {
				if nestedName != "" {
					nestedName += "."
				}
				nestedName += proptools.PropertyNameForField(nested.Name)
				nestedProp := ps.GetByName(nestedName)
				// Anonymous properties may have already been omitted, no need to ensure they are filtered later
				if nestedProp != nil {
					// Set property to anonymous to allow future filtering
					nestedProp.SetAnonymous()
				}
			}
		}
		mt.PropertyStructs = append(mt.PropertyStructs, ps)
	}

	return mt, nil
}

type nestedProperty struct {
	nestPoint string
	value     reflect.Value
	anonymous bool
}

func nestedPropertyStructs(s reflect.Value) []nestedProperty {
	ret := make([]nestedProperty, 0)
	var walk func(structValue reflect.Value, prefix string)
	walk = func(structValue reflect.Value, prefix string) {
		var nestStruct func(field reflect.StructField, value reflect.Value, fieldName string)
		nestStruct = func(field reflect.StructField, value reflect.Value, fieldName string) {
			nestPoint := prefix
			if field.Anonymous {
				nestPoint = strings.TrimSuffix(nestPoint, ".")
			} else {
				nestPoint = nestPoint + proptools.PropertyNameForField(fieldName)
			}
			ret = append(ret, nestedProperty{nestPoint: nestPoint, value: value, anonymous: field.Anonymous})
			if nestPoint != "" {
				nestPoint += "."
			}
			walk(value, nestPoint)
		}

		typ := structValue.Type()
		for i := 0; i < structValue.NumField(); i++ {
			field := typ.Field(i)
			if field.PkgPath != "" {
				// The field is not exported so just skip it.
				continue
			}
			if proptools.HasTag(field, "blueprint", "mutated") {
				continue
			}

			fieldValue := structValue.Field(i)

			switch fieldValue.Kind() {
			case reflect.Bool, reflect.String, reflect.Slice, reflect.Int, reflect.Uint:
				// Nothing
			case reflect.Struct:
				nestStruct(field, fieldValue, field.Name)
			case reflect.Ptr, reflect.Interface:

				if !fieldValue.IsNil() {
					// We leave the pointer intact and zero out the struct that's
					// pointed to.
					elem := fieldValue.Elem()
					if fieldValue.Kind() == reflect.Interface {
						if elem.Kind() != reflect.Ptr {
							panic(fmt.Errorf("can't get type of field %q: interface "+
								"refers to a non-pointer", field.Name))
						}
						elem = elem.Elem()
					}
					if elem.Kind() == reflect.Struct {
						nestStruct(field, elem, field.Name)
					}
				}
			default:
				panic(fmt.Errorf("unexpected kind for property struct field %q: %s",
					field.Name, fieldValue.Kind()))
			}
		}
	}

	walk(s, "")
	return ret
}

// Remove any property structs that have no exported fields
func removeEmptyPropertyStructs(mt *ModuleType) {
	for i := 0; i < len(mt.PropertyStructs); i++ {
		if len(mt.PropertyStructs[i].Properties) == 0 {
			mt.PropertyStructs = append(mt.PropertyStructs[:i], mt.PropertyStructs[i+1:]...)
			i--
		}
	}
}

// Remove any property structs that are anonymous
func removeAnonymousProperties(mt *ModuleType) {
	var removeAnonymousProps func(props []Property) []Property
	removeAnonymousProps = func(props []Property) []Property {
		newProps := make([]Property, 0, len(props))
		for _, p := range props {
			if p.Anonymous {
				continue
			}
			if len(p.Properties) > 0 {
				p.Properties = removeAnonymousProps(p.Properties)
			}
			newProps = append(newProps, p)
		}
		return newProps
	}
	for _, ps := range mt.PropertyStructs {
		ps.Properties = removeAnonymousProps(ps.Properties)
	}
}

// Squashes duplicates of the same property struct into single entries
func collapseDuplicatePropertyStructs(mt *ModuleType) {
	var collapsed []*PropertyStruct

propertyStructLoop:
	for _, from := range mt.PropertyStructs {
		for _, to := range collapsed {
			if from.Name == to.Name {
				CollapseDuplicateProperties(&to.Properties, &from.Properties)
				continue propertyStructLoop
			}
		}
		collapsed = append(collapsed, from)
	}
	mt.PropertyStructs = collapsed
}

func CollapseDuplicateProperties(to, from *[]Property) {
propertyLoop:
	for _, f := range *from {
		for i := range *to {
			t := &(*to)[i]
			if f.Name == t.Name {
				CollapseDuplicateProperties(&t.Properties, &f.Properties)
				continue propertyLoop
			}
		}
		*to = append(*to, f)
	}
}

// Find all property structs that only contain structs, and move their children up one with
// a prefixed name
func collapseNestedPropertyStructs(mt *ModuleType) {
	for _, ps := range mt.PropertyStructs {
		collapseNestedProperties(&ps.Properties)
	}
}

func collapseNestedProperties(p *[]Property) {
	var n []Property

	for _, parent := range *p {
		var containsProperty bool
		for j := range parent.Properties {
			child := &parent.Properties[j]
			if len(child.Properties) > 0 {
				collapseNestedProperties(&child.Properties)
			} else {
				containsProperty = true
			}
		}
		if containsProperty || len(parent.Properties) == 0 {
			n = append(n, parent)
		} else {
			for j := range parent.Properties {
				child := parent.Properties[j]
				child.Name = parent.Name + "." + child.Name
				n = append(n, child)
			}
		}
	}
	*p = n
}

func combineDuplicateProperties(mt *ModuleType) {
	for _, ps := range mt.PropertyStructs {
		combineDuplicateSubProperties(&ps.Properties)
	}
}

func combineDuplicateSubProperties(p *[]Property) {
	var n []Property
propertyLoop:
	for _, child := range *p {
		if len(child.Properties) > 0 {
			combineDuplicateSubProperties(&child.Properties)
			for i := range n {
				s := &n[i]
				if s.SameSubProperties(child) {
					s.OtherNames = append(s.OtherNames, child.Name)
					s.OtherTexts = append(s.OtherTexts, child.Text)
					continue propertyLoop
				}
			}
		}
		n = append(n, child)
	}
	*p = n
}
