// Copyright 2018 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 xeddata

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"strings"
)

// Types for XED enum-like constants.
type (
	// OperandSizeMode describes operand size mode (66H prefix).
	OperandSizeMode int

	// AddressSizeMode describes address size mode (67H prefix).
	AddressSizeMode int

	// CPUMode describes availability in certain CPU mode.
	CPUMode int
)

// Possible operand size modes. XED calls it OSZ.
const (
	OpSize16 OperandSizeMode = iota
	OpSize32
	OpSize64
)

// Possible address size modes. XED calls it ASZ.
const (
	AddrSize16 AddressSizeMode = iota
	AddrSize32
	AddrSize64
)

// Possible CPU modes. XED calls it MODE.
const (
	Mode16 CPUMode = iota
	Mode32
	Mode64
)

var sizeStrings = [...]string{"16", "32", "64"}

// sizeString maps size enumeration value to it's string representation.
func sizeString(size int) string {
	// Panic more gracefully than with "index out of range".
	// If client code specified invalid size enumeration,
	// this is programming error that should be fixed, not "handled".
	if size >= len(sizeStrings) {
		panic(fmt.Sprintf("illegal size value: %d", size))
	}
	return sizeStrings[size]
}

// String returns osz bit size string. Panics on illegal enumerations.
func (osz OperandSizeMode) String() string { return sizeString(int(osz)) }

// String returns asz bit size string. Panics on illegal enumerations.
func (asz AddressSizeMode) String() string { return sizeString(int(asz)) }

// Database holds information that is required to
// properly handle XED datafiles.
type Database struct {
	widths map[string]*width // all-widths.txt
	states map[string]string // all-state.txt
	xtypes map[string]*xtype // all-element-types.txt
}

// width is a "all-width.txt" record.
type width struct {
	// Default xtype name (examples: int, i8, f32).
	xtype string

	// 16, 32 and 64 bit sizes (all may have same value).
	sizes [3]string
}

// xtype is a "all-element-type.txt" record.
type xtype struct {
	// Name is xtype identifier.
	name string

	// baseType specifies xtype base type.
	// See "all-element-type-base.txt".
	baseType string

	// Size is an operand data size in bits.
	size string
}

// NewDatabase returns Database that loads everything
// it can find in xedPath.
// Missing lookup file is not an error, but error during
// parsing of found file is.
//
// Lookup:
//	"$xedPath/all-state.txt" => db.LoadStates()
//	"$xedPath/all-widths.txt" => db.LoadWidths()
//	"$xedPath/all-element-types.txt" => db.LoadXtypes()
// $xedPath is the interpolated value of function argument.
//
// The call NewDatabase("") is valid and returns empty database.
// Load methods can be used to read lookup files one-by-one.
func NewDatabase(xedPath string) (*Database, error) {
	var db Database

	states, err := os.Open(filepath.Join(xedPath, "all-state.txt"))
	if err == nil {
		err = db.LoadStates(states)
		if err != nil {
			return &db, err
		}
	}

	widths, err := os.Open(filepath.Join(xedPath, "all-widths.txt"))
	if err == nil {
		err = db.LoadWidths(widths)
		if err != nil {
			return &db, err
		}
	}

	xtypes, err := os.Open(filepath.Join(xedPath, "all-element-types.txt"))
	if err == nil {
		err = db.LoadXtypes(xtypes)
		if err != nil {
			return &db, err
		}
	}

	return &db, nil
}

// LoadWidths reads XED widths definitions from r and updates db.
// "widths" are 16/32/64 bit mode type sizes.
// See "$XED/obj/dgen/all-widths.txt".
func (db *Database) LoadWidths(r io.Reader) error {
	var err error
	db.widths, err = parseWidths(r)
	return err
}

// LoadStates reads XED states definitions from r and updates db.
// "states" are simple macro substitutions without parameters.
// See "$XED/obj/dgen/all-state.txt".
func (db *Database) LoadStates(r io.Reader) error {
	var err error
	db.states, err = parseStates(r)
	return err
}

// LoadXtypes reads XED xtypes definitions from r and updates db.
// "xtypes" are low-level XED type names.
// See "$XED/obj/dgen/all-element-types.txt".
// See "$XED/obj/dgen/all-element-type-base.txt".
func (db *Database) LoadXtypes(r io.Reader) error {
	var err error
	db.xtypes, err = parseXtypes(r)
	return err
}

// WidthSize translates width string to size string using desired
// SizeMode m. For some widths output is the same for any valid value of m.
func (db *Database) WidthSize(width string, m OperandSizeMode) string {
	info := db.widths[width]
	if info == nil {
		return ""
	}
	return info.sizes[m]
}

func parseWidths(r io.Reader) (map[string]*width, error) {
	data, err := ioutil.ReadAll(r)
	if err != nil {
		return nil, fmt.Errorf("parse widths: %v", err)
	}

	// Lines have two forms:
	// 1. name xtype size [# comment]
	// 2. name xtype size16, size32, size64 [# comment]
	reLine := regexp.MustCompile(`(^\s*\w+\s+\w+\s+\w+\s+\w+\s+\w+)|(^\s*\w+\s+\w+\s+\w+)`)

	widths := make(map[string]*width, 128)
	for _, l := range bytes.Split(data, []byte("\n")) {
		var name, xtype, size16, size32, size64 string

		if m := reLine.FindSubmatch(l); m != nil {
			var f [][]byte
			if m[1] != nil {
				f = bytes.Fields(m[1])
			} else {
				f = bytes.Fields(m[2])
			}

			name = string(f[0])
			xtype = string(f[1])
			if len(f) > 3 {
				size16 = string(f[2])
				size32 = string(f[3])
				size64 = string(f[4])
			} else {
				size16 = string(f[2])
				size32 = size16
				size64 = size16
			}
		}
		if name != "" {
			widths[name] = &width{
				xtype: xtype,
				sizes: [3]string{size16, size32, size64},
			}
		}
	}

	return widths, nil
}

func parseStates(r io.Reader) (map[string]string, error) {
	data, err := ioutil.ReadAll(r)
	if err != nil {
		return nil, fmt.Errorf("parse states: %v", err)
	}

	// Lines have form of "name ...replacements [# comment]".
	// This regexp captures the name and everything until line end or comment.
	lineRE := regexp.MustCompile(`^\s*(\w+)\s+([^#]+)`)

	states := make(map[string]string, 128)
	for _, l := range strings.Split(string(data), "\n") {
		if m := lineRE.FindStringSubmatch(l); m != nil {
			name, replacements := m[1], m[2]
			states[name] = strings.TrimSpace(replacements)
		}
	}

	return states, nil
}

func parseXtypes(r io.Reader) (map[string]*xtype, error) {
	data, err := ioutil.ReadAll(r)
	if err != nil {
		return nil, fmt.Errorf("parse xtypes: %v", err)
	}

	// Lines have form of "name baseType size [# comment]".
	lineRE := regexp.MustCompile(`^\s*(\w+)\s+(\w+)\s*(\d+)`)

	xtypes := make(map[string]*xtype)
	for _, l := range strings.Split(string(data), "\n") {
		if m := lineRE.FindStringSubmatch(l); m != nil {
			name, baseType, size := m[1], m[2], m[3]
			xtypes[name] = &xtype{
				name:     name,
				baseType: baseType,
				size:     size,
			}
		}
	}

	return xtypes, nil
}
