// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"flag"
	"fmt"
	"html/template"
	"io/ioutil"
	"os"
	"path/filepath"
	"sort"
	"strings"

	"github.com/BurntSushi/toml"
	"golang.org/x/vulndb/report"
)

var indexTemplate = template.Must(template.New("index").Parse(`<html>
<body>
	<h1>Go Vulnerability Database</h1>
	<ul>
		{{range .Vulns}}<li><a href="{{.}}.html">{{.}}</a></li>{{end}}
	</ul>
	<h2>Packages</h2>
	<ul>
		{{range .Packages}}<li><a href="{{.}}.html">{{.}}</a></li>{{end}}
	</ul>
</body>
</html>`))
var packageIndexTemplate = template.Must(template.New("package-index").Parse(`<html>
<body>
	<h1>{{.Name}} Vulnerabilities</h1>
	<ul>
		{{range .Vulns}}<li><a href="{{.}}.html">{{.}}</a></li>{{end}}
	</ul>
</body>
</html>`))
var vulnTemplate = template.Must(template.New("vuln").Parse(`<html>
<body>
    <h1>{{.Name}}</h1>
    {{if .Vuln.Severity}}<p><b>Severity: </b>{{.Vuln.Severity}}</p>{{end}}
    {{if .Vuln.OS}}<p><b>Affected Operating Systems: </b>{{.Vuln.OS}}</p>{{end}}
    {{if .Vuln.Arch}}<p><b>Affected Architectures: </b>{{.Vuln.Arch}}</p>{{end}}
	<p>{{.Vuln.Description}}</p>
	{{if .Vuln.Credit}}<p><b>Credit: </b>{{.Vuln.Credit}}</p>{{end}}
	{{if .Vuln.CVE}}<p><b>CVE: </b>{{.Vuln.CVE}}</p>{{end}}

    <h2>Affected Packages</h2>
    <table>
        <tr>
            <th>Package</th>
            <th>Introduced</th>
            <th>Fixed</th>
            <th>Symbols</th>
        </tr>
        <tr>
            <td><code>{{.Vuln.Package}}</code></td>
            {{if not .Vuln.Versions}}<td colspan="2" style="text-align: center">All available versions are vulnerable</td>{{else}}
            {{range .Vuln.Versions}}
            <td style="text-align: center">{{.Introduced}}</td>
            <td style="text-align: center">{{.Fixed}}</td>
            {{end}}
            {{end}}
            <td>
                <ul>
                    {{range .Vuln.Symbols}}<li><code>{{.}}</code></li>{{end}}
                </ul>
            </td>
        </tr>
        {{range .Vuln.AdditionalPackages}}
        <tr>
            <td><code>{{.Package}}</code></td>
            {{if not .Versions}}<td colspan="2" style="text-align: center">All available versions are vulnerable</td>{{else}}
            {{range .Versions}}
            <td style="text-align: center">{{.Introduced}}</td>
            <td style="text-align: center">{{.Fixed}}</td>
            {{end}}
            {{end}}
            <td>
                <ul>
                    {{range .Symbols}}<li><code>{{.}}</code></li>{{end}}
                </ul>
            </td>
        </tr>
        {{end}}
    </table>

	<h2>Context</h2>
	{{if .Vuln.Links.Commit}}<p><b>Commit: </b><a href="{{.Vuln.Links.Commit}}">{{.Vuln.Links.Commit}}</a></p>{{end}}
	{{if .Vuln.Links.PR}}<p><b>PR: </b><a href="{{.Vuln.Links.PR}}">{{.Vuln.Links.PR}}</a></p>{{end}}
	{{if .Vuln.Links.Context}}<p><b>Additional links:</b><ul>{{range .Vuln.Links.Context}}<li><a href="{{.}}">{{.}}</a></li>{{end}}</ul></p>{{end}}
</body>
</html>`))

func generateWebsite(vulns map[string]report.Report, htmlDir string) error {
	index := map[string][]string{}
	var vulnNames []string
	for name, vuln := range vulns {
		index[vuln.Package] = append(index[vuln.Package], name)
		for _, additional := range vuln.AdditionalPackages {
			index[additional.Package] = append(index[additional.Package], name)
		}
		vulnNames = append(vulnNames, name)

		filename := filepath.Join(htmlDir, name+".html")
		file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
		if err != nil {
			return err
		}
		defer file.Close()
		err = vulnTemplate.Execute(file, struct {
			Name string
			Vuln report.Report
		}{
			Name: name,
			Vuln: vuln,
		})
		if err != nil {
			return err
		}
	}

	for p, vulns := range index {
		filename := filepath.Join(htmlDir, p+".html")
		if err := os.MkdirAll(strings.TrimSuffix(filename, filepath.Base(filename)), 0755); err != nil {
			return err
		}
		file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
		if err != nil {
			return err
		}
		defer file.Close()
		err = packageIndexTemplate.Execute(file, struct {
			Name  string
			Vulns []string
		}{
			Name:  p,
			Vulns: vulns,
		})
		if err != nil {
			return err
		}
	}

	var packageNames []string
	for name := range index {
		packageNames = append(packageNames, name)
	}

	sort.Strings(packageNames)
	sort.Strings(vulnNames)
	file, err := os.OpenFile(filepath.Join(htmlDir, "index.html"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
	if err != nil {
		return err
	}
	defer file.Close()
	err = indexTemplate.Execute(file, struct {
		Vulns    []string
		Packages []string
	}{
		Vulns:    vulnNames,
		Packages: packageNames,
	})
	if err != nil {
		return err
	}
	return nil
}

func fail(why string) {
	fmt.Fprintln(os.Stderr, why)
	os.Exit(1)
}

func main() {
	tomlDir := flag.String("reports", "Directory containing toml reports", "")
	htmlDir := flag.String("out", "Directory to write website to", "")
	flag.Parse()

	htmlVulns := map[string]report.Report{}
	tomlFiles, err := ioutil.ReadDir(*tomlDir)
	if err != nil {
		fail(fmt.Sprintf("can't read %q: %s", *tomlDir, err))
	}
	for _, f := range tomlFiles {
		if !strings.HasSuffix(f.Name(), ".toml") {
			continue
		}
		content, err := ioutil.ReadFile(f.Name())
		if err != nil {
			fail(fmt.Sprintf("can't read %q: %s", f.Name(), err))
		}
		var vuln report.Report
		err = toml.Unmarshal(content, &vuln)
		if err != nil {
			fail(fmt.Sprintf("unable to unmarshal %q: %s", f.Name(), err))
		}
		if err = vuln.Lint(); err != nil {
			fail(fmt.Sprintf("invalid vulnerability %q: %s", f.Name(), err))
		}
		name := strings.TrimSuffix(filepath.Base(f.Name()), filepath.Ext(f.Name()))
		htmlVulns[name] = vuln
	}
	err = generateWebsite(htmlVulns, *htmlDir)
	if err != nil {
		fail(fmt.Sprintf("failed to generate website: %s", err))
	}
}
