package iace

import "strings"

// FailureKnowledge is one curated, source-attributed failure record in the
// UNIFIED ontology shared by the FMEA library and the CE hazard side:
//
//	Component → FailureMode → (Mechanism) → Effect → Hazard → Harm → Control
//
// Every source (NASA, OSHA, CPSC, MAUDE, NTSB …) maps into THIS one schema with
// a licence tag. The licence allowlist (FailureKnowledgeLicenseAllowed) rejects
// non-commercial / copyrighted / proprietary sources up front — the same
// discipline that kept FMD-91/NPRD-91 (© IITRI) and DIN/ISO out.
type FailureKnowledge struct {
	ID          string `json:"id"`               // FK-NASA-0001
	Component   string `json:"component"`        // canonical → component library
	FailureMode string `json:"failure_mode"`     // canonical → mode taxonomy
	Mechanism   string `json:"mechanism"`        // cause: fatigue, contamination, wear…
	Effect      string `json:"effect"`           // system-level effect
	Hazard      string `json:"hazard,omitempty"` // EN ISO 12100 category; "" = pure reliability
	Harm        string `json:"harm,omitempty"`
	Control     string `json:"control"` // recommended action / mitigation
	Domain      string `json:"domain"`  // space/aviation/medical/consumer/industrial/general
	Source      string `json:"source"`
	License     string `json:"license"`
	Attribution string `json:"attribution"`
	URL         string `json:"url,omitempty"`
}

// FailureKnowledgeLicenseAllowed reports whether a licence string is a
// commercially-usable open licence. Allowlist by keyword; anything signalling
// "all rights reserved", non-commercial, or a known copyrighted/proprietary
// source is rejected.
func FailureKnowledgeLicenseAllowed(license string) bool {
	l := strings.ToLower(license)
	// Hard rejects first (a copyrighted source may also say "public"…).
	for _, bad := range []string{
		"all rights reserved", "non-commercial", "noncommercial", "cc by-nc", "cc-by-nc",
		"-nd", "no derivatives", "proprietary", "iitri", "quanterion", "oreda",
		"din ", "beuth", "iso ", "iec ", "aiag", "vda", "sae j", "dguv",
	} {
		if strings.Contains(l, bad) {
			return false
		}
	}
	for _, ok := range []string{
		"public domain", "public_use_permitted", "gov_public", "cc0",
		"cc by 4", "cc-by 4", "cc by-sa", "cc-by-sa",
		"open government licence", "ogl", "mit", "apache", "bsd",
		"reproduction authorised", "reproduction authorized",
	} {
		if strings.Contains(l, ok) {
			return true
		}
	}
	return false
}

// GetNASAFailureKnowledge returns the curated NASA lessons-learned starter set
// (US-Gov public domain, NTRS). Each entry is anchored on a real NTRS document;
// fields the source did not state are left empty rather than guessed.
func GetNASAFailureKnowledge() []FailureKnowledge {
	const lic = "Public Domain (NASA NTRS, GOV_PUBLIC_USE_PERMITTED)"
	ntrs := func(id string) string {
		return "https://ntrs.nasa.gov/api/citations/" + id + "/downloads/" + id + ".pdf"
	}
	return []FailureKnowledge{
		{
			ID: "FK-NASA-0001", Component: "flow_control_valve_poppet", FailureMode: "fracture",
			Mechanism: "high-cycle fatigue / contamination", Effect: "sluggish valve response, loss of flow control",
			Control: "contamination control + design margin against resonant fatigue", Domain: "propulsion",
			Source: "NASA NTRS 20110013003", License: lic,
			Attribution: "NASA, Lessons Learned from the SSME Hydrogen Flow Control Valve Poppet Breakage (public domain)",
			URL:         ntrs("20110013003"),
		},
		{
			ID: "FK-NASA-0002", Component: "control_moment_gyroscope", FailureMode: "mechanical_failure",
			Mechanism: "in-service degradation (under investigation)", Effect: "loss of attitude-control actuator",
			Control: "redundancy + condition monitoring + return-for-failure-analysis", Domain: "spacecraft",
			Source: "NASA NTRS 20100021932", License: lic,
			Attribution: "NASA, Space Station Control Moment Gyroscope Lessons Learned (public domain)",
			URL:         ntrs("20100021932"),
		},
		{
			ID: "FK-NASA-0003", Component: "composite_structure", FailureMode: "fracture",
			Mechanism: "accumulation/propagation of damage", Effect: "load-carrying capability below required → structural failure",
			Hazard: "mechanical_hazard", Harm: "structural collapse", Control: "damage-tolerance design + inspection",
			Domain: "structures", Source: "NASA NTRS 20080015747", License: lic,
			Attribution: "NASA, Lessons Learned from Recent Failure and Incident Investigations (public domain)",
			URL:         ntrs("20080015747"),
		},
		{
			ID: "FK-NASA-0004", Component: "pressurized_garment", FailureMode: "ignition",
			Mechanism: "flash fire during functional test", Effect: "unit destroyed",
			Hazard: "fire_explosion", Harm: "fire", Control: "oxygen-fire control + material/ignition-source review",
			Domain: "life_support", Source: "NASA NTRS 20230013281", License: lic,
			Attribution: "NASA, Lessons Learned from the EMU Fire (public domain)",
			URL:         ntrs("20230013281"),
		},
		{
			ID: "FK-NASA-0005", Component: "fuel_cell", FailureMode: "loss_of_function",
			Mechanism: "design conditions leading to component failure", Effect: "loss of electrical power generation",
			Hazard: "electrical_hazard", Control: "design changes per identified failure mode", Domain: "power",
			Source: "NASA NTRS 20090016297", License: lic,
			Attribution: "NASA, Apollo CSM Power Generation System Design Considerations (public domain)",
			URL:         ntrs("20090016297"),
		},
	}
}

// AllFailureKnowledge aggregates every source's curated entries (currently NASA;
// OSHA/CPSC/MAUDE/NTSB will append here as they are added).
func AllFailureKnowledge() []FailureKnowledge {
	var all []FailureKnowledge
	all = append(all, GetNASAFailureKnowledge()...)
	return all
}

// FailureKnowledgeByDomain filters the corpus by domain (e.g. "industrial").
func FailureKnowledgeByDomain(domain string) []FailureKnowledge {
	var out []FailureKnowledge
	for _, fk := range AllFailureKnowledge() {
		if fk.Domain == domain {
			out = append(out, fk)
		}
	}
	return out
}
