// Copyright 2016 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//go:build ignore

package main

import (
	"bufio"
	"bytes"
	"encoding/asn1"
	"errors"
	"fmt"
	"os"
	"os/exec"
	"sort"
	"strconv"
	"strings"
)

func sanitizeName(in string) string {
	in = strings.Replace(in, "-", "_", -1)
	in = strings.Replace(in, ".", "_", -1)
	in = strings.Replace(in, " ", "_", -1)
	return in
}

type object struct {
	name string
	// shortName and longName are the short and long names, respectively. If
	// one is missing, it takes the value of the other, but the
	// corresponding SN_foo or LN_foo macro is not defined.
	shortName, longName       string
	hasShortName, hasLongName bool
	oid                       asn1.ObjectIdentifier
	encoded                   []byte
}

type objects struct {
	// byNID is the list of all objects, indexed by nid.
	byNID []object
	// nameToNID is a map from object name to nid.
	nameToNID map[string]int
}

func readNumbers(path string) (nameToNID map[string]int, numNIDs int, err error) {
	in, err := os.Open(path)
	if err != nil {
		return nil, 0, err
	}
	defer in.Close()

	nameToNID = make(map[string]int)
	nidsSeen := make(map[int]struct{})

	// Reserve NID 0 for NID_undef.
	numNIDs = 1
	nameToNID["undef"] = 0
	nidsSeen[0] = struct{}{}

	var lineNo int
	scanner := bufio.NewScanner(in)
	for scanner.Scan() {
		line := scanner.Text()
		lineNo++
		withLine := func(err error) error {
			return fmt.Errorf("%s:%d: %s", path, lineNo, err)
		}

		fields := strings.Fields(line)
		if len(fields) == 0 {
			// Skip blank lines.
			continue
		}

		// Each line is a name and a nid, separated by space.
		if len(fields) != 2 {
			return nil, 0, withLine(errors.New("syntax error"))
		}
		name := fields[0]
		nid, err := strconv.Atoi(fields[1])
		if err != nil {
			return nil, 0, withLine(err)
		}
		if nid < 0 {
			return nil, 0, withLine(errors.New("invalid NID"))
		}

		// NID_undef is implicitly defined.
		if name == "undef" && nid == 0 {
			continue
		}

		// Forbid duplicates.
		if _, ok := nameToNID[name]; ok {
			return nil, 0, withLine(fmt.Errorf("duplicate name %q", name))
		}
		if _, ok := nidsSeen[nid]; ok {
			return nil, 0, withLine(fmt.Errorf("duplicate NID %d", nid))
		}

		nameToNID[name] = nid
		nidsSeen[nid] = struct{}{}

		if nid >= numNIDs {
			numNIDs = nid + 1
		}
	}
	if err := scanner.Err(); err != nil {
		return nil, 0, fmt.Errorf("error reading %s: %s", path, err)
	}

	return nameToNID, numNIDs, nil
}

func parseOID(aliases map[string]asn1.ObjectIdentifier, in []string) (oid asn1.ObjectIdentifier, err error) {
	if len(in) == 0 {
		return
	}

	// The first entry may be a reference to a previous alias.
	if alias, ok := aliases[sanitizeName(in[0])]; ok {
		in = in[1:]
		oid = append(oid, alias...)
	}

	for _, c := range in {
		val, err := strconv.Atoi(c)
		if err != nil {
			return nil, err
		}
		if val < 0 {
			return nil, fmt.Errorf("negative component")
		}
		oid = append(oid, val)
	}
	return
}

func appendBase128(dst []byte, value int) []byte {
	// Zero is encoded with one, not zero bytes.
	if value == 0 {
		return append(dst, 0)
	}

	// Count how many bytes are needed.
	var l int
	for n := value; n != 0; n >>= 7 {
		l++
	}
	for ; l > 0; l-- {
		b := byte(value>>uint(7*(l-1))) & 0x7f
		if l > 1 {
			b |= 0x80
		}
		dst = append(dst, b)
	}
	return dst
}

func encodeOID(oid []int) []byte {
	if len(oid) < 2 {
		return nil
	}

	var der []byte
	der = appendBase128(der, 40*oid[0]+oid[1])
	for _, value := range oid[2:] {
		der = appendBase128(der, value)
	}
	return der
}

func readObjects(numPath, objectsPath string) (*objects, error) {
	nameToNID, numNIDs, err := readNumbers(numPath)
	if err != nil {
		return nil, err
	}

	in, err := os.Open(objectsPath)
	if err != nil {
		return nil, err
	}
	defer in.Close()

	// Implicitly define NID_undef.
	objs := &objects{
		byNID:     make([]object, numNIDs),
		nameToNID: make(map[string]int),
	}

	objs.byNID[0] = object{
		name:         "undef",
		shortName:    "UNDEF",
		longName:     "undefined",
		hasShortName: true,
		hasLongName:  true,
	}
	objs.nameToNID["undef"] = 0

	var module, nextName string
	var lineNo int
	longNamesSeen := make(map[string]struct{})
	shortNamesSeen := make(map[string]struct{})
	aliases := make(map[string]asn1.ObjectIdentifier)
	scanner := bufio.NewScanner(in)
	for scanner.Scan() {
		line := scanner.Text()
		lineNo++
		withLine := func(err error) error {
			return fmt.Errorf("%s:%d: %s", objectsPath, lineNo, err)
		}

		// Remove comments.
		idx := strings.IndexRune(line, '#')
		if idx >= 0 {
			line = line[:idx]
		}

		// Skip empty lines.
		line = strings.TrimSpace(line)
		if len(line) == 0 {
			continue
		}

		if line[0] == '!' {
			args := strings.Fields(line)
			switch args[0] {
			case "!module":
				if len(args) != 2 {
					return nil, withLine(errors.New("too many arguments"))
				}
				module = sanitizeName(args[1]) + "_"
			case "!global":
				module = ""
			case "!Cname":
				// !Cname directives override the name for the
				// next object.
				if len(args) != 2 {
					return nil, withLine(errors.New("too many arguments"))
				}
				nextName = sanitizeName(args[1])
			case "!Alias":
				// !Alias directives define an alias for an OID
				// without emitting an object.
				if nextName != "" {
					return nil, withLine(errors.New("!Cname directives may not modify !Alias directives."))
				}
				if len(args) < 3 {
					return nil, withLine(errors.New("not enough arguments"))
				}
				aliasName := module + sanitizeName(args[1])
				oid, err := parseOID(aliases, args[2:])
				if err != nil {
					return nil, withLine(err)
				}
				if _, ok := aliases[aliasName]; ok {
					return nil, withLine(fmt.Errorf("duplicate name '%s'", aliasName))
				}
				aliases[aliasName] = oid
			default:
				return nil, withLine(fmt.Errorf("unknown directive '%s'", args[0]))
			}
			continue
		}

		fields := strings.Split(line, ":")
		if len(fields) < 2 || len(fields) > 3 {
			return nil, withLine(errors.New("invalid field count"))
		}

		obj := object{name: nextName}
		nextName = ""

		var err error
		obj.oid, err = parseOID(aliases, strings.Fields(fields[0]))
		if err != nil {
			return nil, withLine(err)
		}
		obj.encoded = encodeOID(obj.oid)

		obj.shortName = strings.TrimSpace(fields[1])
		if len(fields) == 3 {
			obj.longName = strings.TrimSpace(fields[2])
		}

		// Long and short names default to each other if missing.
		if len(obj.shortName) == 0 {
			obj.shortName = obj.longName
		} else {
			obj.hasShortName = true
		}
		if len(obj.longName) == 0 {
			obj.longName = obj.shortName
		} else {
			obj.hasLongName = true
		}
		if len(obj.shortName) == 0 || len(obj.longName) == 0 {
			return nil, withLine(errors.New("object with no name"))
		}

		// If not already specified, prefer the long name if it has no
		// spaces, otherwise the short name.
		if len(obj.name) == 0 && strings.IndexRune(obj.longName, ' ') < 0 {
			obj.name = sanitizeName(obj.longName)
		}
		if len(obj.name) == 0 {
			obj.name = sanitizeName(obj.shortName)
		}
		obj.name = module + obj.name

		// Check for duplicate names.
		if _, ok := aliases[obj.name]; ok {
			return nil, withLine(fmt.Errorf("duplicate name '%s'", obj.name))
		}
		if _, ok := shortNamesSeen[obj.shortName]; ok && len(obj.shortName) > 0 {
			return nil, withLine(fmt.Errorf("duplicate short name '%s'", obj.shortName))
		}
		if _, ok := longNamesSeen[obj.longName]; ok && len(obj.longName) > 0 {
			return nil, withLine(fmt.Errorf("duplicate long name '%s'", obj.longName))
		}

		// Allocate a NID.
		nid, ok := nameToNID[obj.name]
		if !ok {
			nid = len(objs.byNID)
			objs.byNID = append(objs.byNID, object{})
		}

		objs.byNID[nid] = obj
		objs.nameToNID[obj.name] = nid

		longNamesSeen[obj.longName] = struct{}{}
		shortNamesSeen[obj.shortName] = struct{}{}
		aliases[obj.name] = obj.oid
	}
	if err := scanner.Err(); err != nil {
		return nil, err
	}

	// The kNIDsIn*Order constants assume each NID fits in a uint16_t.
	if len(objs.byNID) > 0xffff {
		return nil, errors.New("too many NIDs allocated")
	}

	return objs, nil
}

func writeNumbers(path string, objs *objects) error {
	out, err := os.Create(path)
	if err != nil {
		return err
	}
	defer out.Close()

	for nid, obj := range objs.byNID {
		if len(obj.name) == 0 {
			continue
		}
		if _, err := fmt.Fprintf(out, "%s\t\t%d\n", obj.name, nid); err != nil {
			return err
		}
	}
	return nil
}

func clangFormat(input string) (string, error) {
	var b bytes.Buffer
	cmd := exec.Command("clang-format")
	cmd.Stdin = strings.NewReader(input)
	cmd.Stdout = &b
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err != nil {
		return "", err
	}
	return b.String(), nil
}

func writeHeader(path string, objs *objects) error {
	var b bytes.Buffer
	fmt.Fprintf(&b, `// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// This file is generated by crypto/obj/objects.go.

#ifndef OPENSSL_HEADER_NID_H
#define OPENSSL_HEADER_NID_H

#include <openssl/base.h>  // IWYU pragma: export

#if defined(__cplusplus)
extern "C" {
#endif


// The nid library provides numbered values for ASN.1 object identifiers and
// other symbols. These values are used by other libraries to identify
// cryptographic primitives.
//
// A separate objects library, obj.h, provides functions for converting between
// nids and object identifiers. However it depends on large internal tables with
// the encodings of every nid defined. Consumers concerned with binary size
// should instead embed the encodings of the few consumed OIDs and compare
// against those.
//
// Constants are defined as follows:
//
// - NID_foo is the integer NID of foo.
// - SN_foo is the "short name" of foo, omitted if there is no short name.
// - LN_foo is the "long name" of foo, omitted if there is no long name.
// - OBJ_foo expands to a comma-separated sequence of integers for foo's OID,
//   omitted if foo has no OID.
// - OBJ_ENC_foo expands to a comma-separated sequence of bytes for foo's OID
//   encoded in DER, excluding the tag and length. This is omitted if foo has
//   no OID.
//
// NID values should not be used outside of a single process; they are not
// stable identifiers.


`)

	for nid, obj := range objs.byNID {
		if len(obj.name) == 0 {
			continue
		}

		if obj.hasShortName {
			fmt.Fprintf(&b, "#define SN_%s \"%s\"\n", obj.name, obj.shortName)
		}
		if obj.hasLongName {
			fmt.Fprintf(&b, "#define LN_%s \"%s\"\n", obj.name, obj.longName)
		}
		fmt.Fprintf(&b, "#define NID_%s %d\n", obj.name, nid)

		// Although NID_undef does not have an OID, OpenSSL emits
		// OBJ_undef as if it were zero.
		oid := obj.oid
		if nid == 0 {
			oid = asn1.ObjectIdentifier{0}
		}
		if len(oid) != 0 {
			var oidStr strings.Builder
			for _, val := range oid {
				if oidStr.Len() != 0 {
					oidStr.WriteString(", ")
				}
				fmt.Fprintf(&oidStr, "%dL", val)
			}
			fmt.Fprintf(&b, "#define OBJ_%s %s\n", obj.name, oidStr.String())
		}
		// Some NIDs refer to the top-level OID arcs, which cannot be encoded
		// as OIDs. (The encoding can only represent two or more components.)
		if len(oid) > 1 {
			var oidEncStr strings.Builder
			for _, val := range encodeOID(oid) {
				if oidEncStr.Len() != 0 {
					oidEncStr.WriteString(", ")
				}
				fmt.Fprintf(&oidEncStr, "0x%02x", val)
			}
			fmt.Fprintf(&b, "#define OBJ_ENC_%s %s\n", obj.name, oidEncStr.String())
		}

		fmt.Fprintf(&b, "\n")
	}

	fmt.Fprintf(&b, `
#if defined(__cplusplus)
}  /* extern C */
#endif

#endif  /* OPENSSL_HEADER_NID_H */
`)

	formatted, err := clangFormat(b.String())
	if err != nil {
		return err
	}

	return os.WriteFile(path, []byte(formatted), 0666)
}

func sortNIDs(nids []int, objs *objects, cmp func(a, b object) bool) {
	sort.Slice(nids, func(i, j int) bool { return cmp(objs.byNID[nids[i]], objs.byNID[nids[j]]) })
}

func writeData(path string, objs *objects) error {
	var b bytes.Buffer
	fmt.Fprintf(&b, `// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// This file is generated by crypto/obj/objects.go.


`)

	fmt.Fprintf(&b, "#define NUM_NID %d\n", len(objs.byNID))

	// Emit each object's DER encoding, concatenated, and save the offsets.
	fmt.Fprintf(&b, "\nstatic const uint8_t kObjectData[] = {\n")
	offsets := make([]int, len(objs.byNID))
	var nextOffset int
	for nid, obj := range objs.byNID {
		if len(obj.name) == 0 || len(obj.encoded) == 0 {
			offsets[nid] = -1
			continue
		}

		offsets[nid] = nextOffset
		nextOffset += len(obj.encoded)
		fmt.Fprintf(&b, "/* NID_%s */\n", obj.name)
		for _, val := range obj.encoded {
			fmt.Fprintf(&b, "0x%02x, ", val)
		}
		fmt.Fprintf(&b, "\n")
	}
	fmt.Fprintf(&b, "};\n")

	// Emit an ASN1_OBJECT for each object.
	fmt.Fprintf(&b, "\nstatic const ASN1_OBJECT kObjects[NUM_NID] = {\n")
	for nid, obj := range objs.byNID {
		// Skip the entry for NID_undef. It is stored separately, so that
		// OBJ_get_undef avoids pulling in the table.
		if nid == 0 {
			continue
		}

		if len(obj.name) == 0 {
			fmt.Fprintf(&b, "{NULL, NULL, NID_undef, 0, NULL, 0},\n")
			continue
		}

		fmt.Fprintf(&b, "{\"%s\", \"%s\", NID_%s, ", obj.shortName, obj.longName, obj.name)
		if offset := offsets[nid]; offset >= 0 {
			fmt.Fprintf(&b, "%d, &kObjectData[%d], 0},\n", len(obj.encoded), offset)
		} else {
			fmt.Fprintf(&b, "0, NULL, 0},\n")
		}
	}
	fmt.Fprintf(&b, "};\n")

	// Emit a list of NIDs sorted by short name.
	var nids []int
	for nid, obj := range objs.byNID {
		if len(obj.name) == 0 || len(obj.shortName) == 0 {
			continue
		}
		nids = append(nids, nid)
	}
	sortNIDs(nids, objs, func(a, b object) bool { return a.shortName < b.shortName })

	fmt.Fprintf(&b, "\nstatic const uint16_t kNIDsInShortNameOrder[] = {\n")
	for _, nid := range nids {
		// Including NID_undef in the table does not do anything. Whether OBJ_sn2nid
		// finds the object or not, it will return NID_undef.
		if nid != 0 {
			fmt.Fprintf(&b, "%d /* %s */,\n", nid, objs.byNID[nid].shortName)
		}
	}
	fmt.Fprintf(&b, "};\n")

	// Emit a list of NIDs sorted by long name.
	nids = nil
	for nid, obj := range objs.byNID {
		if len(obj.name) == 0 || len(obj.longName) == 0 {
			continue
		}
		nids = append(nids, nid)
	}
	sortNIDs(nids, objs, func(a, b object) bool { return a.longName < b.longName })

	fmt.Fprintf(&b, "\nstatic const uint16_t kNIDsInLongNameOrder[] = {\n")
	for _, nid := range nids {
		// Including NID_undef in the table does not do anything. Whether OBJ_ln2nid
		// finds the object or not, it will return NID_undef.
		if nid != 0 {
			fmt.Fprintf(&b, "%d /* %s */,\n", nid, objs.byNID[nid].longName)
		}
	}
	fmt.Fprintf(&b, "};\n")

	// Emit a list of NIDs sorted by OID.
	nids = nil
	for nid, obj := range objs.byNID {
		if len(obj.name) == 0 || len(obj.encoded) == 0 {
			continue
		}
		nids = append(nids, nid)
	}
	sortNIDs(nids, objs, func(a, b object) bool {
		// This comparison must match the definition of |obj_cmp|.
		if len(a.encoded) < len(b.encoded) {
			return true
		}
		if len(a.encoded) > len(b.encoded) {
			return false
		}
		return bytes.Compare(a.encoded, b.encoded) < 0
	})

	fmt.Fprintf(&b, "\nstatic const uint16_t kNIDsInOIDOrder[] = {\n")
	for _, nid := range nids {
		obj := objs.byNID[nid]
		fmt.Fprintf(&b, "%d /* ", nid)
		for i, c := range obj.oid {
			if i > 0 {
				fmt.Fprintf(&b, ".")
			}
			fmt.Fprintf(&b, "%d", c)
		}
		fmt.Fprintf(&b, " (OBJ_%s) */,\n", obj.name)
	}
	fmt.Fprintf(&b, "};\n")

	formatted, err := clangFormat(b.String())
	if err != nil {
		return err
	}

	return os.WriteFile(path, []byte(formatted), 0666)
}

func main() {
	objs, err := readObjects("obj_mac.num", "objects.txt")
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error reading objects: %s\n", err)
		os.Exit(1)
	}

	if err := writeNumbers("obj_mac.num", objs); err != nil {
		fmt.Fprintf(os.Stderr, "Error writing numbers: %s\n", err)
		os.Exit(1)
	}

	if err := writeHeader("../../include/openssl/nid.h", objs); err != nil {
		fmt.Fprintf(os.Stderr, "Error writing header: %s\n", err)
		os.Exit(1)
	}

	if err := writeData("obj_dat.h", objs); err != nil {
		fmt.Fprintf(os.Stderr, "Error writing data: %s\n", err)
		os.Exit(1)
	}
}
