/* SPDX-License-Identifier: GPL-2.0-or-later */

package main

import (
	"encoding/csv"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strconv"
	"strings"
)

/*
 * This program allocates DRAM strap IDs for different parts that are being used by the variant.
 *
 * It expects the following inputs:
 *  Name of the SoC platform, e.g. TGL.
 *  Memory technology used by the variant, e.g. lp4x.
 *  Path to Makefile directory. Makefile.mk generated by this program is placed in this
 *  location.
 *  Text file containing a list of memory part names used by the board. Each line in the file
 *  is expected to have one memory part name.
 */
const (
	SPDManifestFileName       = "parts_spd_manifest.generated.txt"
	PlatformsManifestFileName = "platforms_manifest.generated.txt"
	SPDEmptyFileName          = "spd-empty.hex"
	MakefileName              = "Makefile.mk"
	DRAMIdFileName            = "dram_id.generated.txt"
	MaxMemoryId               = 15
)

var supportedPlatforms = [...]string{
	"TGL",
	"ADL",
	"JSL",
	"PCO",
	"CZN",
	"MDN",
	"MTL",
	"PHX",
}

var supportedMemTechs = [...]string{
	"lp4x",
	"ddr4",
	"lp5",
}

func usage() {
	fmt.Printf("\nUsage: %s <platform> <mem_technology> <makefile_dir> <mem_parts_used_file>\n\n", os.Args[0])
	fmt.Printf("   where,\n")
	fmt.Printf("   platform = SoC platform which the board is based on\n")
	fmt.Printf("              supported platforms: %v\n", supportedPlatforms)
	fmt.Printf("   mem_technology = Memory technology used by the board\n")
	fmt.Printf("                    supported technologies: %v\n", supportedMemTechs)
	fmt.Printf("   makefile_dir = Directory path where generated Makefile.mk should be placed\n")
	fmt.Printf("   mem_parts_used_file = CSV file containing list of memory parts used by the board and optional fixed ids\n\n\n")
}

func checkArgs(platform string, memTech string, makefileDir string, memPartsUsedFile string) error {
	supported := false
	for _, p := range supportedPlatforms {
		if strings.ToUpper(platform) == p {
			supported = true
			break
		}
	}
	if !supported {
		return fmt.Errorf("Platform %s is not supported", platform)
	}

	supported = false
	for _, m := range supportedMemTechs {
		if strings.ToLower(memTech) == m {
			supported = true
			break
		}
	}
	if !supported {
		return fmt.Errorf("Memory technology %s is not supported", memTech)
	}

	if _, err := os.Stat(makefileDir); err != nil {
		return fmt.Errorf("Invalid makefile_dir %s: %v", makefileDir, err)
	}

	if _, err := os.Stat(memPartsUsedFile); err != nil {
		return fmt.Errorf("Invalid mem_parts_used_file %s: %v", memPartsUsedFile, err)
	}

	return nil
}

type mappingType int

const (
	Auto mappingType = iota
	Fixed
	Exclusive
)

type usedPart struct {
	partName    string
	index       int
	mapping     mappingType
	SPDOverride string
}

func readPlatformsManifest(memTech string) (map[string]string, error) {
	manifestFilePath := filepath.Join("spd", strings.ToLower(memTech), PlatformsManifestFileName)
	f, err := os.Open(manifestFilePath)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	r := csv.NewReader(f)
	r.Comment = '#'

	platformToSetMap := make(map[string]string)

	for {
		fields, err := r.Read()

		if err == io.EOF {
			break
		}

		if err != nil {
			return nil, err
		}

		if len(fields) != 2 {
			return nil, fmt.Errorf("Platforms manifest file is incorrectly formatted: %s", manifestFilePath)
		}

		platformToSetMap[fields[0]] = fields[1]
	}

	return platformToSetMap, nil
}

func getSPDDir(platform string, memTech string) (string, error) {
	platformToSetMap, err := readPlatformsManifest(memTech)
	if err != nil {
		return "", err
	}

	setName, ok := platformToSetMap[strings.ToUpper(platform)]
	if !ok {
		return "", fmt.Errorf("Platform %s does not support memory technology %s", platform, memTech)
	}

	return filepath.Join("spd", strings.ToLower(memTech), setName), nil
}

/*
 * Read input file CSV that contains list of memory part names used by the variant
 * and an optional assigned id.
 */
func readParts(memPartsUsedFileName string) ([]usedPart, error) {
	f, err := os.Open(memPartsUsedFileName)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	r := csv.NewReader(f)
	r.FieldsPerRecord = -1 // Allow variable length records
	r.TrimLeadingSpace = true
	r.Comment = '#'

	parts := []usedPart{}

	for {
		fields, err := r.Read()

		if err == io.EOF {
			break
		}

		if err != nil {
			return nil, err
		}

		if len(fields) == 1 {
			parts = append(parts, usedPart{fields[0], -1, Auto, ""})
		} else {
			var mapping = Auto
			var assignedId = -1
			var err error = nil
			var spdOverride string = ""

			// Second column, ID override
			if len(fields) >= 2 {
				if len(fields[1]) >= 2 && fields[1][0] == '*' {
					// Exclusive mapping
					mapping = Exclusive
					assignedId, err = strconv.Atoi(fields[1][1:])
				} else if fields[1] != "" {
					// Fixed mapping
					mapping = Fixed
					assignedId, err = strconv.Atoi(fields[1])
				}
			}

			// Third column, SPD file override
			if len(fields) >= 3 {
				if len(fields[2]) == 0 {
					err = fmt.Errorf("mem_parts_used_file file is incorrectly formatted, SPD file column is empty")
				} else {
					spdOverride = fields[2]
				}
			}

			if err != nil {
				return nil, err
			}

			if assignedId > MaxMemoryId {
				return nil, fmt.Errorf("Out of bounds assigned id %d for part %s", assignedId, fields[0])
			}

			parts = append(parts, usedPart{fields[0], assignedId, mapping, spdOverride})
		}
	}

	return parts, nil
}

/*
 * Read SPD manifest file(CSV) generated by gen_spd program and generate two maps:
 * 1. Part to SPD Map : This maps global memory part name to generated SPD file name
 * 2. SPD to Index Map: This generates a map of deduplicated SPD file names to index assigned to
 *                      that SPD. This function sets the index for all SPDs to -1. This index gets
 *                      updated as part of genPartIdInfo() depending upon the SPDs actually used
 *                      by the variant.
 */
func readSPDManifest(SPDDirName string) (map[string]string, map[string]int, error) {
	f, err := os.Open(filepath.Join(SPDDirName, SPDManifestFileName))
	if err != nil {
		return nil, nil, err
	}
	defer f.Close()
	r := csv.NewReader(f)
	r.Comment = '#'

	partToSPDMap := make(map[string]string)
	SPDToIndexMap := make(map[string]int)

	for {
		fields, err := r.Read()

		if err == io.EOF {
			break
		}

		if err != nil {
			return nil, nil, err
		}

		if len(fields) != 2 {
			return nil, nil, fmt.Errorf("CSV file is incorrectly formatted")
		}

		partToSPDMap[fields[0]] = fields[1]
		SPDToIndexMap[fields[1]] = -1
	}

	return partToSPDMap, SPDToIndexMap, nil
}

/* Print information about memory part used by variant and ID assigned to it. */
func appendPartIdInfo(s *string, partName string, index int) {
	*s += fmt.Sprintf("%-30s %d (%04b)\n", partName, index, int64(index))
}

type partIds struct {
	SPDFileName string
	memParts    string
}

func getFileHeader() string {
	return `# SPDX-License-Identifier: GPL-2.0-or-later
# This is an auto-generated file. Do not edit!!
# Generated by:
` + fmt.Sprintf("# %s\n\n", strings.Join(os.Args[0:], " "))
}

/*
 * For each part used by the variant, check if the SPD (as per the manifest) already has an ID
 * assigned to it. If yes, then add the part name to the list of memory parts supported by the
 * SPD entry. If not, then assign the next ID to the SPD file and add the part name to the
 * list of memory parts supported by the SPD entry.
 *
 * Returns list of partIds that contains spdFileName and supported memory parts for each
 * assigned ID.
 */
func genPartIdInfo(parts []usedPart, partToSPDMap map[string]string, SPDToIndexMap map[string]int, makefileDirName string) ([]partIds, error) {
	partIdList := []partIds{}
	assignedMapping := []mappingType{}
	var s string

	// Assign parts with fixed ids first
	for _, p := range parts {
		if p.index == -1 {
			continue
		}

		if p.partName == "" {
			return nil, fmt.Errorf("Invalid part entry")
		}

		SPDFileName, ok := partToSPDMap[p.partName]
		if !ok {
			return nil, fmt.Errorf("Failed to find part %s in SPD Manifest. Please add the part to global part list and regenerate SPD Manifest", p.partName)
		}

		// Extend partIdList and assignedMapping with empty entries if needed
		for i := len(partIdList) - 1; i < p.index; i++ {
			partIdList = append(partIdList, partIds{})
			assignedMapping = append(assignedMapping, Auto)
		}

		// Only allow parts with the same index if they share the same SPD
		assignedSPD := partIdList[p.index].SPDFileName
		if assignedSPD != "" && assignedSPD != partToSPDMap[p.partName] {
			return nil, fmt.Errorf("ID %d is already assigned to %s, conflicting with %s(%s)", p.index, assignedSPD, p.partName, SPDFileName)
		}

		mapping := assignedMapping[p.index]
		if (mapping == Fixed && p.mapping == Exclusive) || (mapping == Exclusive && p.mapping == Fixed) {
			return nil, fmt.Errorf("Exclusive/non-exclusive conflict in assigning %s to ID %d", p.partName, p.index)
		} else {
			assignedMapping[p.index] = p.mapping
		}

		if partIdList[p.index].memParts == "" {
			partIdList[p.index] = partIds{SPDFileName: SPDFileName, memParts: p.partName}
		} else {
			partIdList[p.index].memParts += ", " + p.partName
		}

		// SPDToIndexMap should point to first assigned index in the used part list
		// Exclusive entries don't update the map because they're not valid for auto assigning
		if SPDToIndexMap[SPDFileName] < 0 && p.mapping != Exclusive {
			SPDToIndexMap[SPDFileName] = p.index
		}
	}

	s += fmt.Sprintf("%-30s %s\n", "DRAM Part Name", "ID to assign")

	// Assign parts with no fixed id
	for _, p := range parts {
		if p.partName == "" {
			return nil, fmt.Errorf("Invalid part entry")
		}

		// Add assigned parts to dram id file in the order they appear
		if p.index != -1 {
			appendPartIdInfo(&s, p.partName, p.index)
			continue
		}

		SPDFileName, ok := partToSPDMap[p.partName]
		if !ok {
			return nil, fmt.Errorf("Failed to find part ", p.partName, " in SPD Manifest. Please add the part to global part list and regenerate SPD Manifest")
		}

		index := SPDToIndexMap[SPDFileName]
		// Only Exclusive mappings don't allow automatic assigning of parts
		if index != -1 && assignedMapping[index] != Exclusive {
			partIdList[index].memParts += ", " + p.partName
			appendPartIdInfo(&s, p.partName, index)
			continue
		}

		// Find first empty index
		for i, partId := range partIdList {
			if partId.SPDFileName == "" {
				index = i
				break
			}
		}

		// Append new entry
		if index == -1 {
			index = len(partIdList)
			if index > MaxMemoryId {
				return nil, fmt.Errorf("Maximum part ID %d exceeded.", MaxMemoryId)
			}
			partIdList = append(partIdList, partIds{})
			assignedMapping = append(assignedMapping, Auto)
		}

		SPDToIndexMap[SPDFileName] = index
		appendPartIdInfo(&s, p.partName, index)
		partIdList[index] = partIds{SPDFileName: SPDFileName, memParts: p.partName}
	}

	fmt.Printf("%s", s)

	s = getFileHeader() + s
	err := ioutil.WriteFile(filepath.Join(makefileDirName, DRAMIdFileName), []byte(s), 0644)

	return partIdList, err
}

/*
 * This function generates Makefile.mk under the variant directory path and adds assigned SPDs
 * to SPD_SOURCES.
 */
func genMakefile(partIdList []partIds, makefileDirName string, SPDDir string, partsDir string) error {
	s := getFileHeader()
	s += fmt.Sprintf("SPD_SOURCES =\n")

	for i := 0; i < len(partIdList); i++ {
		if partIdList[i].SPDFileName == "" {
			s += fmt.Sprintf("SPD_SOURCES += %v ", filepath.Join(SPDDir, SPDEmptyFileName))
			s += fmt.Sprintf("     # ID = %d(0b%04b)\n", i, int64(i))
		} else {
			SPDFileName := partIdList[i].SPDFileName
			path := filepath.Join(partsDir, SPDFileName)

			// Check if the file exists in the directory of the parts file
			if _, err := os.Stat(path); err != nil {
				// File doesn't exist, check spd directory
				path = filepath.Join(SPDDir, SPDFileName)
				if _, err = os.Stat(path); err != nil {
					return fmt.Errorf("Failed to write Makefile, SPD file '%s' doesn't exist", SPDFileName)
				}
			}
			s += fmt.Sprintf("SPD_SOURCES += %v ", path)
			s += fmt.Sprintf("     # ID = %d(0b%04b) ", i, int64(i))
			s += fmt.Sprintf(" Parts = %04s\n", partIdList[i].memParts)
		}
	}

	return ioutil.WriteFile(filepath.Join(makefileDirName, MakefileName), []byte(s), 0644)
}

func main() {
	if len(os.Args) != 5 {
		usage()
		log.Fatal("Incorrect number of arguments")
	}

	platform, memTech, makefileDir, memPartsUsedFile := os.Args[1], os.Args[2], os.Args[3], os.Args[4]

	err := checkArgs(platform, memTech, makefileDir, memPartsUsedFile)
	if err != nil {
		log.Fatal(err)
	}

	SPDDir, err := getSPDDir(platform, memTech)
	if err != nil {
		log.Fatal(err)
	}

	partToSPDMap, SPDToIndexMap, err := readSPDManifest(SPDDir)
	if err != nil {
		log.Fatal(err)
	}

	parts, err := readParts(memPartsUsedFile)
	if err != nil {
		log.Fatal(err)
	}

	// Update our SPD maps with part specific overrides
	for _, p := range parts {
		if p.SPDOverride != "" {
			partToSPDMap[p.partName] = p.SPDOverride
			SPDToIndexMap[p.SPDOverride] = -1
		}
	}

	partIdList, err := genPartIdInfo(parts, partToSPDMap, SPDToIndexMap, makefileDir)
	if err != nil {
		log.Fatal(err)
	}

	if err := genMakefile(partIdList, makefileDir, SPDDir, filepath.Dir(memPartsUsedFile)); err != nil {
		log.Fatal(err)
	}
}
