package main

import (
	
	

	
)

var htmlEscaper = strings.NewReplacer(
	"\n", "
", // for Markdown compatibility
	// From Go’s html package.
	`&`, "&",
	`'`, "'", // "'" is shorter than "'" and apos was not in HTML until HTML5.
	`<`, "&lt;",
	`>`, "&gt;",
	`"`, "&#34;", // "&#34;" is shorter than "&quot;".
)

type htmlGenerator struct {
	w io.Writer

	docsURL string
}

func ( io.Writer,  *report) error {
	 := &htmlGenerator{, "https://pkg.go.dev/"}
	if  := .visitReport();  != nil {
		return 
	}
	return nil
}

func ( *htmlGenerator) ( *report) error {
	if  := .visitStateDiff(.State);  != nil {
		return 
	}
	if  := .visitTestReport(.Tests);  != nil {
		return 
	}
	return nil
}

func ( *htmlGenerator) ( stateDiff) error {
	if len(.Updated) == 0 && len(.Removed) == 0 && len(.Added) == 0 {
		return nil
	}
	if  := .visitStateDiffUpdated(.Updated);  != nil {
		return 
	}
	if  := .visitStateDiffAdded(.Added);  != nil {
		return 
	}
	if  := .visitStateDiffRemoved(.Removed);  != nil {
		return 
	}
	return nil
}

func ( *htmlGenerator) ( []moduleDiff) error {
	var ,  []moduleDiff
	for ,  := range  {
		if .Unchanged() {
			 = append(, )
		} else {
			 = append(, )
		}
	}
	for ,  := range  {
		if  := .visitModuleDiff();  != nil {
			return 
		}
	}
	for ,  := range  {
		if  := .visitModuleDiff();  != nil {
			return 
		}
	}
	return nil
}

func ( *htmlGenerator) ( moduleDiff) error {
	return .htmlDetails(func() error {
		if  := .moduleUpgradeSummary(.Path, .Old.Version, .New.Version, .Unchanged());  != nil {
			return 
		}
		if  := .visitModuleDiffChanged(.Changed);  != nil {
			return 
		}
		if  := .visitModuleDiffRemoved(.Removed);  != nil {
			return 
		}
		if  := .visitModuleDiffAdded(.Removed);  != nil {
			return 
		}
		if  := .visitModuleDiffOldBroken(.OldBroken);  != nil {
			return 
		}
		if  := .visitModuleDiffNewBroken(.NewBroken);  != nil {
			return 
		}
		return nil
	})
}

func ( *htmlGenerator) (, ,  string,  bool) error {
	return .htmlSummary(func() error {
		var  string
		if  {
			 = "\U0001F7F0 " // heavy equals sign
		} else {
			 = "\u2797 " // heavy divide sign
		}
		if  := .writeString();  != nil {
			return 
		}
		if  := .htmlAnchorText(.docsURL+, );  != nil {
			return 
		}
		if  := .writeString("@");  != nil {
			return 
		}
		if  := .htmlAnchorText(.docsURL++"@"+, );  != nil {
			return 
		}
		if  := .writeString(" \u27f9 ");  != nil { // long rightwards double arrow
			return 
		}
		if  := .htmlAnchorText(.docsURL++"@"+, );  != nil {
			return 
		}
		return nil
	})
}

func ( *htmlGenerator) ( []packageDiff) error {
	if len() == 0 {
		return nil
	}
	if  := .htmlHeaderText("Changed packages");  != nil {
		return 
	}
	if  := .listPackageDiffs();  != nil {
		return 
	}
	return nil
}

func ( *htmlGenerator) ( []packageDiff) error {
	return .htmlUnorderedList(func() error {
		for ,  := range  {
			if  := .visitPackageDiff();  != nil {
				return 
			}
		}
		return nil
	})
}

func ( *htmlGenerator) ( packageDiff) error {
	return .htmlListItem(func() error {
		if  := .htmlCodeText(.Path);  != nil {
			return 
		}
		if  := .htmlPreSampText(.Diff.String());  != nil {
			return 
		}
		return nil
	})
}

func ( *htmlGenerator) ( []*packages.Package) error {
	return .listPackages("Added packages", )
}

func ( *htmlGenerator) ( []*packages.Package) error {
	return .listPackages("Removed packages", )
}

func ( *htmlGenerator) ( []*packages.Package) error {
	return .listPackages("Old package errors", )
}

func ( *htmlGenerator) ( []*packages.Package) error {
	return .listPackages("New package errors", )
}

func ( *htmlGenerator) ( string,  []*packages.Package) error {
	if len() == 0 {
		return nil
	}
	if  := .htmlHeaderText();  != nil {
		return 
	}
	return .htmlUnorderedList(func() error {
		for ,  := range  {
			if  := .listItemPackageWithErrors();  != nil {
				return 
			}
		}
		return nil
	})
}

func ( *htmlGenerator) ( *packages.Package) error {
	return .htmlListItem(func() error {
		if  := .htmlCodeText(.PkgPath);  != nil {
			return 
		}
		for ,  := range .Errors {
			if  := .htmlPreSampText(.Error());  != nil {
				return 
			}
		}
		return nil
	})
}

func ( *htmlGenerator) ( []packages.Module) error {
	return .listModules("\u2795", ) // heavy plus sign
}

func ( *htmlGenerator) ( []packages.Module) error {
	return .listModules("\u2796", ) // heavy minus sign
}

func ( *htmlGenerator) ( string,  []packages.Module) error {
	for ,  := range  {
		if  := .emptyModuleDetails(, );  != nil {
			return 
		}
	}
	return nil
}

func ( *htmlGenerator) ( packages.Module,  string) error {
	return .htmlDetails(func() error {
		return .htmlSummary(func() error {
			if  := .writeString( + " ");  != nil {
				return 
			}
			if  := .htmlAnchorText(.docsURL+.Path, .Path);  != nil {
				return 
			}
			if  := .writeString("@");  != nil {
				return 
			}
			if  := .htmlAnchorText(.docsURL+.Path+"@"+.Version, .Version);  != nil {
				return 
			}
			return nil
		})
	})
}

func ( *htmlGenerator) ( *testReport) error {
	if  == nil {
		return nil
	}
	if  := .htmlHorizontalRule();  != nil {
		return 
	}
	return .htmlDetails(func() error {
		if  := .visitTestReportFailed(.Failed, .Decode != nil);  != nil {
			return 
		}
		if  := .visitTestReportEvents(.Events);  != nil {
			return 
		}
		if  := .visitTestReportDecode(.Decode, .Buffer);  != nil {
			return 
		}
		if  := .visitTestReportStderr(.Stderr);  != nil {
			return 
		}
		return nil
	})
}

func ( *htmlGenerator) (,  bool) error {
	var  string
	switch {
	case :
		 = "\u274C Tests: failed" // cross mark
	case :
		 = "\u26A0\uFE0F Tests: passed (malformed output)" // warning sign
	default:
		 = "\u2714\uFE0F Tests: passed" // heavy check mark
	}
	return .htmlSummaryText()
}

func ( *htmlGenerator) ( []testEvent) error {
	return .htmlPreSamp(func() error {
		for ,  := range  {
			if .Output == nil {
				continue
			}
			if  := .writeString(*.Output);  != nil {
				return 
			}
		}
		return nil
	})
}

func ( *htmlGenerator) ( error,  []byte) error {
	if  == nil {
		return nil
	}
	if  := .htmlPreSampText(.Error());  != nil {
		return 
	}
	return .htmlDetails(func() error {
		if  := .htmlSummaryText("Malformed output");  != nil {
			return 
		}
		if  := .writeBytes();  != nil {
			return 
		}
		return nil
	})
}

func ( *htmlGenerator) ( []byte) error {
	if len() == 0 {
		return nil
	}
	return .htmlPreSamp(func() error {
		return .writeBytes()
	})
}

func ( *htmlGenerator) ( string) error {
	return .html("h4", nil, nil, func() error {
		return .writeString()
	}, true)
}

func ( *htmlGenerator) ( func() error) error {
	return .html("ul", nil, nil, , true)
}

func ( *htmlGenerator) ( func() error) error {
	return .html("li", nil, nil, , true)
}

func ( *htmlGenerator) ( func() error) error {
	return .html("details", nil, nil, , true)
}

func ( *htmlGenerator) ( string) error {
	return .htmlSummary(func() error {
		return .writeString()
	})
}

func ( *htmlGenerator) ( func() error) error {
	return .html("summary", nil, nil, , true)
}

func ( *htmlGenerator) ( string) error {
	return .htmlPreSamp(func() error {
		return .writeString(strings.TrimSuffix(, "\n"))
	})
}

func ( *htmlGenerator) ( func() error) error {
	return .html("pre", nil, nil, func() error {
		return .html("samp", nil, nil, , true)
	}, true)
}

func ( *htmlGenerator) ( string) error {
	return .html("code", nil, nil, func() error {
		return .writeString()
	}, true)
}

func ( *htmlGenerator) (,  string) error {
	return .htmlAnchor(, func() error {
		return .writeString()
	})
}

func ( *htmlGenerator) ( string,  func() error) error {
	return .html("a", []string{"href"}, map[string]string{"href": }, , true)
}

func ( *htmlGenerator) () error {
	return .html("hr", nil, nil, nil, true)
}

func ( *htmlGenerator) ( string,  []string,  map[string]string,  func() error,  bool) error {
	if  := .writeRawString(`<`);  != nil {
		return 
	}
	if  := .writeRawString();  != nil {
		return 
	}
	for ,  := range  {
		if  := .writeRawString(" ");  != nil {
			return 
		}
		if  := .writeRawString();  != nil {
			return 
		}
		,  := []
		if ! {
			continue
		}
		if  := .writeRawString("=");  != nil {
			return 
		}
		if  := .writeString();  != nil {
			return 
		}
	}
	if  := .writeRawString(`>`);  != nil {
		return 
	}
	if  != nil {
		if  := ();  != nil {
			return 
		}
	}
	if ! {
		return nil
	}
	if  := .writeRawString(`</`);  != nil {
		return 
	}
	if  := .writeRawString();  != nil {
		return 
	}
	if  := .writeRawString(`>`);  != nil {
		return 
	}
	return nil
}

func ( *htmlGenerator) ( []byte) error {
	return .writeString(string())
}

func ( *htmlGenerator) ( string) error {
	,  := htmlEscaper.WriteString(.w, )
	return 
}

func ( *htmlGenerator) ( string) error {
	,  := io.WriteString(.w, )
	return 
}