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)

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

		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
}
