// Copyright 2021 The Wuffs 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
// +build ignore

package main

// gen.go generates data.go.
//
// Invoke it via "go generate".

import (
	"bytes"
	"fmt"
	"go/format"
	"os"
	"strings"

	ani "github.com/google/wuffs/lib/armneonintrinsics"
)

func main() {
	if err := main1(); err != nil {
		os.Stderr.WriteString(err.Error() + "\n")
		os.Exit(1)
	}
}

func main1() error {
	out.WriteString(header)
	for i, aniType := range [...]ani.Type{
		ani.TypeUint8x8,
		ani.TypeUint16x4,
		ani.TypeUint32x2,
		ani.TypeUint64x1,
		ani.TypeUint8x16,
		ani.TypeUint16x8,
		ani.TypeUint32x4,
		ani.TypeUint64x2,
	} {
		if i != 0 {
			out.WriteByte('\n')
		}
		if err := do(aniType); err != nil {
			return err
		}
	}
	out.WriteString(footer)

	formatted, err := format.Source(out.Bytes())
	if err != nil {
		return err
	}
	return os.WriteFile("data.go", formatted, 0644)
}

var (
	out bytes.Buffer
)

func do(aniType ani.Type) error {
	wtnRecv := wuffsTypeNames[aniType]
outer:
	for f := ani.FirstFunction(); f.IsValid(); f = f.NextFunction() {
		if f.FirstArgument().Type() != aniType {
			continue
		}
		fName := f.Name()
		if strings.HasPrefix(fName, "vreinterpret_") ||
			strings.HasPrefix(fName, "vreinterpretq_") {
			continue
		}

		for arg := f.FirstArgument(); arg.IsValid(); arg = arg.NextArgument() {
			if wuffsTypeNames[arg.Type()] == "" {
				fmt.Fprintf(&out, "// %s.%s(etc)\n", wtnRecv, fName)
				continue outer
			}
		}

		laney := strings.Contains(fName, "_lane")
		fmt.Fprintf(&out, "\"%s.%s(", wtnRecv, fName)

		prevArgType := ani.Type(0)
		for i, arg := 0, f.FirstArgument(); arg.IsValid(); i, arg = i+1, arg.NextArgument() {
			wtnArg := wuffsTypeNames[arg.Type()]
			refinement := ""
			if laney && (wtnArg[0] != 'a') {
				refinement = refinements[prevArgType]
			}

			prevArgType = arg.Type()
			if i == 0 {
				continue
			} else if i > 1 {
				out.WriteString(", ")
			}
			fmt.Fprintf(&out, "%s: %v%s",
				stripUnderscores(arg.Name()),
				wuffsTypeNames[arg.Type()],
				refinement)
		}
		out.WriteString(") ")
		out.WriteString(wuffsTypeNames[f.ReturnType()])
		out.WriteString("\",\n")
	}
	return nil
}

func stripUnderscores(s string) string {
	for (s != "") && (s[0] == '_') {
		s = s[1:]
	}
	return s
}

var refinements = [256]string{
	ani.TypeUint8x8:  "[..= 7]",
	ani.TypeUint16x4: "[..= 3]",
	ani.TypeUint32x2: "[..= 1]",
	ani.TypeUint64x1: "[..= 0]",

	ani.TypeUint8x16: "[..= 15]",
	ani.TypeUint16x8: "[..= 7]",
	ani.TypeUint32x4: "[..= 3]",
	ani.TypeUint64x2: "[..= 1]",
}

var wuffsTypeNames = [256]string{
	ani.TypeInt8:        "u8",
	ani.TypeInt16:       "u16",
	ani.TypeInt32:       "u32",
	ani.TypeInt64:       "u64",
	ani.TypeUint8:       "u8",
	ani.TypeUint16:      "u16",
	ani.TypeUint32:      "u32",
	ani.TypeUint64:      "u64",
	ani.TypeConstInt8:   "u8",
	ani.TypeConstInt16:  "u16",
	ani.TypeConstInt32:  "u32",
	ani.TypeConstInt64:  "u64",
	ani.TypeConstUint8:  "u8",
	ani.TypeConstUint16: "u16",
	ani.TypeConstUint32: "u32",
	ani.TypeConstUint64: "u64",

	ani.TypeUint8x8:  "arm_neon_u8x8",
	ani.TypeUint16x4: "arm_neon_u16x4",
	ani.TypeUint32x2: "arm_neon_u32x2",
	ani.TypeUint64x1: "arm_neon_u64x1",

	ani.TypeUint8x16: "arm_neon_u8x16",
	ani.TypeUint16x8: "arm_neon_u16x8",
	ani.TypeUint32x4: "arm_neon_u32x4",
	ani.TypeUint64x2: "arm_neon_u64x2",
}

const header = `// Code generated by running "go generate". DO NOT EDIT.

// Copyright 2021 The Wuffs 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.

package builtin

var funcsARMNeon = [...]string {
`

const footer = "}\n"
