// 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.

// +build ignore

package main

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

import (
	"bytes"
	"fmt"
	"go/format"
	"io/ioutil"
	"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 ioutil.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"
