// Copyright (c) 2014, Google Inc.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

package main

import (
	"bufio"
	"errors"
	"flag"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
)

// ssl.h reserves values 1000 and above for error codes corresponding to
// alerts. If automatically assigned reason codes exceed this value, this script
// will error. This must be kept in sync with SSL_AD_REASON_OFFSET in ssl.h.
const reservedReasonCode = 1000

var resetFlag *bool = flag.Bool("reset", false, "If true, ignore current assignments and reassign from scratch")

type libraryInfo struct {
	sourceDirs []string
	headerName string
}

func getLibraryInfo(lib string) libraryInfo {
	var info libraryInfo
	if lib == "ssl" {
		info.sourceDirs = []string{"ssl"}
	} else {
		info.sourceDirs = []string{
			filepath.Join("crypto", lib),
			filepath.Join("crypto", lib+"_extra"),
			filepath.Join("crypto", "fipsmodule", lib),
		}
	}
	info.headerName = lib + ".h"

	if lib == "evp" {
		info.headerName = "evp_errors.h"
		info.sourceDirs = append(info.sourceDirs, filepath.Join("crypto", "hpke"))
	}

	return info
}

func makeErrors(lib string, reset bool) error {
	topLevelPath, err := findToplevel()
	if err != nil {
		return err
	}

	info := getLibraryInfo(lib)

	headerPath := filepath.Join(topLevelPath, "include", "openssl", info.headerName)
	errDir := filepath.Join(topLevelPath, "crypto", "err")
	dataPath := filepath.Join(errDir, lib+".errordata")

	headerFile, err := os.Open(headerPath)
	if err != nil {
		if os.IsNotExist(err) {
			return fmt.Errorf("No header %s. Run in the right directory or touch the file.", headerPath)
		}

		return err
	}

	prefix := strings.ToUpper(lib)
	reasons, err := parseHeader(prefix, headerFile)
	headerFile.Close()

	if reset {
		err = nil
		// Retain any reason codes above reservedReasonCode.
		newReasons := make(map[string]int)
		for key, value := range reasons {
			if value >= reservedReasonCode {
				newReasons[key] = value
			}
		}
		reasons = newReasons
	}

	if err != nil {
		return err
	}

	for _, sourceDir := range info.sourceDirs {
		fullPath := filepath.Join(topLevelPath, sourceDir)
		dir, err := os.Open(fullPath)
		if err != nil {
			if os.IsNotExist(err) {
				// Some directories in the search path may not exist.
				continue
			}
			return err
		}
		defer dir.Close()
		filenames, err := dir.Readdirnames(-1)
		if err != nil {
			return err
		}

		for _, name := range filenames {
			if !strings.HasSuffix(name, ".c") && !strings.HasSuffix(name, ".cc") {
				continue
			}

			if err := addReasons(reasons, filepath.Join(fullPath, name), prefix); err != nil {
				return err
			}
		}
	}

	assignNewValues(reasons, reservedReasonCode)

	headerFile, err = os.Open(headerPath)
	if err != nil {
		return err
	}
	defer headerFile.Close()

	newHeaderFile, err := os.OpenFile(headerPath+".tmp", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
	if err != nil {
		return err
	}
	defer newHeaderFile.Close()

	if err := writeHeaderFile(newHeaderFile, headerFile, prefix, reasons); err != nil {
		return err
	}
	// Windows forbids renaming an open file.
	headerFile.Close()
	newHeaderFile.Close()
	if err := os.Rename(headerPath+".tmp", headerPath); err != nil {
		return err
	}

	dataFile, err := os.OpenFile(dataPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
	if err != nil {
		return err
	}

	outputStrings(dataFile, lib, reasons)
	dataFile.Close()

	return nil
}

func findToplevel() (path string, err error) {
	path = "."
	buildingPath := filepath.Join(path, "BUILDING.md")

	_, err = os.Stat(buildingPath)
	for i := 0; i < 2 && err != nil && os.IsNotExist(err); i++ {
		if i == 0 {
			path = ".."
		} else {
			path = filepath.Join("..", path)
		}
		buildingPath = filepath.Join(path, "BUILDING.md")
		_, err = os.Stat(buildingPath)
	}
	if err != nil {
		return "", errors.New("Cannot find BUILDING.md file at the top-level")
	}
	return path, nil
}

type assignment struct {
	key   string
	value int
}

type assignmentsSlice []assignment

func (a assignmentsSlice) Len() int {
	return len(a)
}

func (a assignmentsSlice) Less(i, j int) bool {
	return a[i].value < a[j].value
}

func (a assignmentsSlice) Swap(i, j int) {
	a[i], a[j] = a[j], a[i]
}

func outputAssignments(w io.Writer, assignments map[string]int) {
	var sorted assignmentsSlice

	for key, value := range assignments {
		sorted = append(sorted, assignment{key, value})
	}

	sort.Sort(sorted)

	for _, assignment := range sorted {
		fmt.Fprintf(w, "#define %s %d\n", assignment.key, assignment.value)
	}
}

func parseDefineLine(line, lib string) (key string, value int, ok bool) {
	if !strings.HasPrefix(line, "#define ") {
		return
	}

	fields := strings.Fields(line)
	if len(fields) != 3 {
		return
	}

	key = fields[1]
	if !strings.HasPrefix(key, lib+"_R_") {
		return
	}

	var err error
	if value, err = strconv.Atoi(fields[2]); err != nil {
		return
	}

	ok = true
	return
}

func writeHeaderFile(w io.Writer, headerFile io.Reader, lib string, reasons map[string]int) error {
	var last []byte
	var haveLast, sawDefine bool
	newLine := []byte("\n")

	scanner := bufio.NewScanner(headerFile)
	for scanner.Scan() {
		line := scanner.Text()
		_, _, ok := parseDefineLine(line, lib)
		if ok {
			sawDefine = true
			continue
		}

		if haveLast {
			w.Write(last)
			w.Write(newLine)
		}

		if len(line) > 0 || !sawDefine {
			last = []byte(line)
			haveLast = true
		} else {
			haveLast = false
		}
		sawDefine = false
	}

	if err := scanner.Err(); err != nil {
		return err
	}

	outputAssignments(w, reasons)
	w.Write(newLine)

	if haveLast {
		w.Write(last)
		w.Write(newLine)
	}

	return nil
}

func outputStrings(w io.Writer, lib string, assignments map[string]int) {
	lib = strings.ToUpper(lib)
	prefixLen := len(lib + "_R_")

	keys := make([]string, 0, len(assignments))
	for key := range assignments {
		keys = append(keys, key)
	}
	sort.Strings(keys)

	for _, key := range keys {
		fmt.Fprintf(w, "%s,%d,%s\n", lib, assignments[key], key[prefixLen:])
	}
}

func assignNewValues(assignments map[string]int, reserved int) {
	// Needs to be in sync with the reason limit in
	// |ERR_reason_error_string|.
	max := 99

	for _, value := range assignments {
		if reserved >= 0 && value >= reserved {
			continue
		}
		if value > max {
			max = value
		}
	}

	max++

	// Sort the keys, so this script is reproducible.
	keys := make([]string, 0, len(assignments))
	for key, value := range assignments {
		if value == -1 {
			keys = append(keys, key)
		}
	}
	sort.Strings(keys)

	for _, key := range keys {
		if reserved >= 0 && max >= reserved {
			// If this happens, try passing -reset. Otherwise bump
			// up reservedReasonCode.
			panic("Automatically-assigned values exceeded limit!")
		}
		assignments[key] = max
		max++
	}
}

func handleDeclareMacro(line, join, macroName string, m map[string]int) {
	if i := strings.Index(line, macroName); i >= 0 {
		contents := line[i+len(macroName):]
		if i := strings.Index(contents, ")"); i >= 0 {
			contents = contents[:i]
			args := strings.Split(contents, ",")
			for i := range args {
				args[i] = strings.TrimSpace(args[i])
			}
			if len(args) != 2 {
				panic("Bad macro line: " + line)
			}
			token := args[0] + join + args[1]
			if _, ok := m[token]; !ok {
				m[token] = -1
			}
		}
	}
}

func addReasons(reasons map[string]int, filename, prefix string) error {
	file, err := os.Open(filename)
	if err != nil {
		return err
	}
	defer file.Close()

	reasonPrefix := prefix + "_R_"

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		line := scanner.Text()

		handleDeclareMacro(line, "_R_", "OPENSSL_DECLARE_ERROR_REASON(", reasons)

		for len(line) > 0 {
			i := strings.Index(line, prefix+"_")
			if i == -1 {
				break
			}

			line = line[i:]
			end := strings.IndexFunc(line, func(r rune) bool {
				return !(r == '_' || (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9'))
			})
			if end == -1 {
				end = len(line)
			}

			var token string
			token, line = line[:end], line[end:]

			switch {
			case strings.HasPrefix(token, reasonPrefix):
				if _, ok := reasons[token]; !ok {
					reasons[token] = -1
				}
			}
		}
	}

	return scanner.Err()
}

func parseHeader(lib string, file io.Reader) (reasons map[string]int, err error) {
	reasons = make(map[string]int)

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		key, value, ok := parseDefineLine(scanner.Text(), lib)
		if !ok {
			continue
		}

		reasons[key] = value
	}

	err = scanner.Err()
	return
}

func main() {
	flag.Parse()
	if flag.NArg() == 0 {
		fmt.Fprintf(os.Stderr, "Usage: make_errors.go LIB [LIB2...]\n")
		os.Exit(1)
	}

	for _, lib := range flag.Args() {
		if err := makeErrors(lib, *resetFlag); err != nil {
			fmt.Fprintf(os.Stderr, "Error generating errors for %q: %s\n", lib, err)
			os.Exit(1)
		}
	}
}
