package parser

import (
	"bufio"
	"fmt"
	"strings"
	"strconv"

	"review.coreboot.org/coreboot.git/util/intelp2m/platforms/common"
	"review.coreboot.org/coreboot.git/util/intelp2m/platforms/snr"
	"review.coreboot.org/coreboot.git/util/intelp2m/platforms/lbg"
	"review.coreboot.org/coreboot.git/util/intelp2m/platforms/apl"
	"review.coreboot.org/coreboot.git/util/intelp2m/platforms/cnl"
	"review.coreboot.org/coreboot.git/util/intelp2m/platforms/adl"
	"review.coreboot.org/coreboot.git/util/intelp2m/platforms/jsl"
	"review.coreboot.org/coreboot.git/util/intelp2m/config"
)

// PlatformSpecific - platform-specific interface
type PlatformSpecific interface {
	GenMacro(id string, dw0 uint32, dw1 uint32, ownership uint8) string
	GroupNameExtract(line string) (bool, string)
	KeywordCheck(line string) bool
}

// padInfo - information about pad
// id        : pad id string
// offset    : the offset of the register address relative to the base
// function  : the string that means the pad function
// dw0       : DW0 register value
// dw1       : DW1 register value
// ownership : host software ownership
type padInfo struct {
	id        string
	offset    uint16
	function  string
	dw0       uint32
	dw1       uint32
	ownership uint8
}

// generate - wrapper for Fprintf(). Writes text to the file specified
// in config.OutputGenFile
func (info *padInfo) generate(lvl int, line string, a ...interface{}) {
	if config.InfoLevelGet() >= lvl {
		fmt.Fprintf(config.OutputGenFile, line, a...)
	}
}

// titleFprint - print GPIO group title to file
// /* ------- GPIO Group GPP_L ------- */
func (info *padInfo) titleFprint() {
	info.generate(0, "\n\t/* %s */\n", info.function)
}

// reservedFprint - print reserved GPIO to file as comment
// /* GPP_H17 - RESERVED */
func (info *padInfo) reservedFprint() {
	info.generate(2, "\n")
	// small comment about reserved port
	info.generate(0, "\t/* %s - %s */\n", info.id, info.function)
}

// padInfoMacroFprint - print information about current pad to file using
// special macros:
// PAD_CFG_NF(GPP_F1, 20K_PU, PLTRST, NF1), /* SATAXPCIE4 */
// gpio  : gpio.c file descriptor
// macro : string of the generated macro
func (info *padInfo) padInfoMacroFprint(macro string) {
	info.generate(2,
		"\n\t/* %s - %s */\n\t/* DW0: 0x%0.8x, DW1: 0x%0.8x */\n",
		info.id,
		info.function,
		info.dw0,
		info.dw1)
	info.generate(0, "\t%s", macro)
	if config.InfoLevelGet() == 1 {
		info.generate(1, "\t/* %s */", info.function)
	}
	info.generate(0, "\n")
}

// ParserData - global data
// line       : string from the configuration file
// padmap     : pad info map
// RawFmt     : flag for generating pads config file with DW0/1 reg raw values
// Template   : structure template type of ConfigFile
type ParserData struct {
	platform   PlatformSpecific
	line       string
	padmap     []padInfo
	ownership  map[string]uint32
}

// hostOwnershipGet - get the host software ownership value for the corresponding
// pad ID
// id : pad ID string
// return the host software ownership form the parser struct
func (parser *ParserData) hostOwnershipGet(id string) uint8 {
	var ownership uint8 = 0
	status, group := parser.platform.GroupNameExtract(id)
	if config.TemplateGet() == config.TempInteltool && status {
		numder, _ := strconv.Atoi(strings.TrimLeft(id, group))
		if (parser.ownership[group] & (1 << uint8(numder))) != 0 {
			ownership = 1
		}
	}
	return ownership
}

// padInfoExtract - adds a new entry to pad info map
// return error status
func (parser *ParserData) padInfoExtract() int {
	var function, id string
	var dw0, dw1 uint32
	var template = map[int]template{
		config.TempInteltool: useInteltoolLogTemplate,
		config.TempGpioh    : useGpioHTemplate,
		config.TempSpec     : useYourTemplate,
	}
	if template[config.TemplateGet()](parser.line, &function, &id, &dw0, &dw1) == 0 {
		pad := padInfo{id: id,
			function: function,
			dw0: dw0,
			dw1: dw1,
			ownership: parser.hostOwnershipGet(id)}
		parser.padmap = append(parser.padmap, pad)
		return 0
	}
	fmt.Printf("This template (%d) does not match!\n", config.TemplateGet())
	return -1
}

// communityGroupExtract
func (parser *ParserData) communityGroupExtract() {
	pad := padInfo{function: parser.line}
	parser.padmap = append(parser.padmap, pad)
}

// PlatformSpecificInterfaceSet - specific interface for the platform selected
// in the configuration
func (parser *ParserData) PlatformSpecificInterfaceSet() {
	var platform = map[uint8]PlatformSpecific {
		config.SunriseType   : snr.PlatformSpecific{},
		// See platforms/lbg/macro.go
		config.LewisburgType : lbg.PlatformSpecific{
			InheritanceTemplate : snr.PlatformSpecific{},
		},
		config.ApolloType    : apl.PlatformSpecific{},
		config.CannonType    : cnl.PlatformSpecific{
			InheritanceTemplate : snr.PlatformSpecific{},
		},
		config.AlderType     : adl.PlatformSpecific{},
		config.JasperType    : jsl.PlatformSpecific{},
	}
	parser.platform = platform[config.PlatformGet()]
}

// PadMapFprint - print pad info map to file
func (parser *ParserData) PadMapFprint() {
	for _, pad := range parser.padmap {
		switch pad.dw0 {
		case 0:
			pad.titleFprint()
		case 0xffffffff:
			pad.reservedFprint()
		default:
			str := parser.platform.GenMacro(pad.id, pad.dw0, pad.dw1, pad.ownership)
			pad.padInfoMacroFprint(str)
		}
	}
}

// Register - read specific platform registers (32 bits)
// line         : string from file with pad config map
// nameTemplate : register name femplate to filter parsed lines
// return
//     valid  : true if the dump of the register in intertool.log is set in accordance
//              with the template
//     name   : full register name
//     offset : register offset relative to the base address
//     value  : register value
func (parser *ParserData) Register(nameTemplate string) (
		valid bool, name string, offset uint32, value uint32) {
	if strings.Contains(parser.line, nameTemplate) &&
		config.TemplateGet() == config.TempInteltool {
		if registerInfoTemplate(parser.line, &name, &offset, &value) == 0 {
			fmt.Printf("\n\t/* %s : 0x%x : 0x%x */\n", name, offset, value)
			return true, name, offset, value
		}
	}
	return false, "ERROR", 0, 0
}

// padOwnershipExtract - extract Host Software Pad Ownership from inteltool dump
//                       return true if success
func (parser *ParserData) padOwnershipExtract() bool {
	var group string
	status, name, offset, value := parser.Register("HOSTSW_OWN_GPP_")
	if status {
		_, group = parser.platform.GroupNameExtract(parser.line)
		parser.ownership[group] = value
		fmt.Printf("\n\t/* padOwnershipExtract: [offset 0x%x] %s = 0x%x */\n",
				offset, name, parser.ownership[group])
	}
	return status
}

// padConfigurationExtract - reads GPIO configuration registers and returns true if the
//                           information from the inteltool log was successfully parsed.
func (parser *ParserData) padConfigurationExtract() bool {
	// Only for Sunrise or CannonLake, and only for inteltool.log file template
	if config.TemplateGet() != config.TempInteltool || config.IsPlatformApollo() {
		return false
	}
	return parser.padOwnershipExtract()
}

// Parse pads groupe information in the inteltool log file
// ConfigFile : name of inteltool log file
func (parser *ParserData) Parse() {
	// Read all lines from inteltool log file
	fmt.Println("Parse IntelTool Log File...")

	// determine the platform type and set the interface for it
	parser.PlatformSpecificInterfaceSet()

	// map of thepad ownership registers for the GPIO controller
	parser.ownership = make(map[string]uint32)

	scanner := bufio.NewScanner(config.InputRegDumpFile)
	for scanner.Scan() {
		parser.line = scanner.Text()
		isIncluded, _ := common.KeywordsCheck(parser.line, "GPIO Community", "GPIO Group");
		if isIncluded {
			parser.communityGroupExtract()
		} else if !parser.padConfigurationExtract() && parser.platform.KeywordCheck(parser.line) {
			if parser.padInfoExtract() != 0 {
				fmt.Println("...error!")
			}
		}
	}
	fmt.Println("...done!")
}
