// Package javadocs provides parsing and extraction for Java documentation
// from docs.oracle.com and javadoc-generated sites.
package javadocs

import "time"

// Package represents a Java package's documentation.
type Package struct {
	Name        string    `json:"name"`
	Doc         string    `json:"doc,omitempty"`
	Version     string    `json:"version,omitempty"`
	DocURL      string    `json:"doc_url"`
	Classes     []*Class  `json:"classes,omitempty"`
	Interfaces  []*Class  `json:"interfaces,omitempty"`
	Enums       []*Enum   `json:"enums,omitempty"`
	Exceptions  []*Class  `json:"exceptions,omitempty"`
	Annotations []*Class  `json:"annotations,omitempty"`
	FetchedAt   time.Time `json:"fetched_at"`
}

// Class represents a Java class or interface.
type Class struct {
	QualifiedName string    `json:"qualified_name"`
	Name          string    `json:"name"`
	Package       string    `json:"package"`
	Kind          ClassKind `json:"kind"`
	Doc           string    `json:"doc,omitempty"`
	Modifiers     []string  `json:"modifiers,omitempty"`
	SuperClass    string    `json:"super_class,omitempty"`
	Interfaces    []string  `json:"interfaces,omitempty"`
	Fields        []*Field  `json:"fields,omitempty"`
	Methods       []*Method `json:"methods,omitempty"`
	Constructors  []*Method `json:"constructors,omitempty"`
	NestedClasses []*Class  `json:"nested_classes,omitempty"`
	DocURL        string    `json:"doc_url"`
	Since         string    `json:"since,omitempty"`
	Deprecated    string    `json:"deprecated,omitempty"`
}

// ClassKind represents the kind of class.
type ClassKind string

const (
	ClassKindClass      ClassKind = "class"
	ClassKindInterface  ClassKind = "interface"
	ClassKindAnnotation ClassKind = "annotation"
	ClassKindRecord     ClassKind = "record"
	ClassKindSealed     ClassKind = "sealed"
)

// Enum represents a Java enum.
type Enum struct {
	QualifiedName string       `json:"qualified_name"`
	Name          string       `json:"name"`
	Package       string       `json:"package"`
	Doc           string       `json:"doc,omitempty"`
	Modifiers     []string     `json:"modifiers,omitempty"`
	Constants     []*EnumConst `json:"constants,omitempty"`
	Methods       []*Method    `json:"methods,omitempty"`
	DocURL        string       `json:"doc_url"`
	Since         string       `json:"since,omitempty"`
}

// EnumConst represents an enum constant.
type EnumConst struct {
	Name   string `json:"name"`
	Doc    string `json:"doc,omitempty"`
	DocURL string `json:"doc_url"`
}

// Field represents a class field.
type Field struct {
	Name       string   `json:"name"`
	Type       string   `json:"type"`
	Doc        string   `json:"doc,omitempty"`
	Modifiers  []string `json:"modifiers,omitempty"`
	Value      string   `json:"value,omitempty"`
	DocURL     string   `json:"doc_url"`
	Deprecated string   `json:"deprecated,omitempty"`
}

// Method represents a method or constructor.
type Method struct {
	Name          string       `json:"name"`
	Doc           string       `json:"doc,omitempty"`
	Modifiers     []string     `json:"modifiers,omitempty"`
	ReturnType    string       `json:"return_type,omitempty"`
	Parameters    []*Parameter `json:"parameters,omitempty"`
	Exceptions    []string     `json:"exceptions,omitempty"`
	Signature     string       `json:"signature"`
	QualifiedName string       `json:"qualified_name"`
	DocURL        string       `json:"doc_url"`
	Since         string       `json:"since,omitempty"`
	Deprecated    string       `json:"deprecated,omitempty"`
	IsConstructor bool         `json:"is_constructor"`
	IsStatic      bool         `json:"is_static"`
	IsDefault     bool         `json:"is_default"`
}

// Parameter represents a method parameter.
type Parameter struct {
	Name string `json:"name"`
	Type string `json:"type"`
	Doc  string `json:"doc,omitempty"`
}

// SearchResult represents a search result.
type SearchResult struct {
	Name     string `json:"name"`
	QualName string `json:"qualified_name"`
	Kind     string `json:"kind"` // class, interface, enum, method, field
	Package  string `json:"package"`
	Doc      string `json:"doc,omitempty"`
	DocURL   string `json:"doc_url"`
	Score    int    `json:"score"`
}
