/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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
 *
 *  http://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 builder

import (
	"bufio"
	"fmt"
	"os"
	"path/filepath"
	"sort"
	"strconv"
	"strings"

	"mynewt.apache.org/newt/newt/image"
	"mynewt.apache.org/newt/util"
	"mynewt.apache.org/newt/newt/interfaces"
)

/*
 * These are different memory regions as specified in linker script.
 */
type MemSection struct {
	Name   string
	Offset uint64
	EndOff uint64
}
type MemSectionArray []*MemSection

var globalMemSections map[string]*MemSection

func (array MemSectionArray) Len() int {
	return len(array)
}

func (array MemSectionArray) Less(i, j int) bool {
	return array[i].Offset < array[j].Offset
}

func (array MemSectionArray) Swap(i, j int) {
	array[i], array[j] = array[j], array[i]
}

func MakeMemSection(name string, off uint64, size uint64) *MemSection {
	memsection := &MemSection{
		Name:   name,
		Offset: off,
		EndOff: off + size,
	}
	return memsection
}

func (m *MemSection) PartOf(addr uint64) bool {
	if addr >= m.Offset && addr < m.EndOff {
		return true
	} else {
		return false
	}
}

/*
 * Info about specific symbol size
 */
type SymbolData struct {
	Name    string
	ObjName string            /* Which object file it came from */
	Sizes   map[string]uint32 /* Sizes indexed by mem section name */
}

type SymbolDataArray []*SymbolData

/*
 * We accumulate the size of libraries to elements in this.
 */
type PkgSize struct {
	Name  string
	Sizes map[string]uint32      /* Sizes indexed by mem section name */
	Syms  map[string]*SymbolData /* Symbols indexed by symbol name */
}

type PkgSizeArray []*PkgSize

func (array PkgSizeArray) Len() int {
	return len(array)
}

func (array PkgSizeArray) Less(i, j int) bool {
	return array[i].Name < array[j].Name
}

func (array PkgSizeArray) Swap(i, j int) {
	array[i], array[j] = array[j], array[i]
}

func (array SymbolDataArray) Len() int {
	return len(array)
}

func (array SymbolDataArray) Less(i, j int) bool {
	return array[i].Name < array[j].Name
}

func (array SymbolDataArray) Swap(i, j int) {
	array[i], array[j] = array[j], array[i]
}

func MakeSymbolData(name string, objName string) *SymbolData {
	sym := &SymbolData{
		Name:    name,
		ObjName: objName,
	}
	sym.Sizes = make(map[string]uint32)
	for _, sec := range globalMemSections {
		sym.Sizes[sec.Name] = 0
	}
	return sym
}

func MakePkgSize(name string) *PkgSize {
	pkgSize := &PkgSize{
		Name: name,
	}
	pkgSize.Sizes = make(map[string]uint32)
	for _, sec := range globalMemSections {
		pkgSize.Sizes[sec.Name] = 0
	}
	pkgSize.Syms = make(map[string]*SymbolData)
	return pkgSize
}

func (ps *PkgSize) addSymSize(symName string, objName string, size uint32, addr uint64) {
	for _, section := range globalMemSections {
		if section.PartOf(addr) {
			name := section.Name
			size32 := uint32(size)
			if size32 > 0 {
				sym := ps.Syms[symName]
				if sym == nil {
					sym = MakeSymbolData(symName, objName)
					ps.Syms[symName] = sym
				}
				ps.Sizes[name] += size32
				sym.Sizes[name] += size32
			}
			break
		}
	}
}

/*
 * Go through GCC generated mapfile, and collect info about symbol sizes
 */
func ParseMapFileSizes(fileName string) (map[string]*PkgSize, error) {
	var state int = 0

	file, err := os.Open(fileName)
	if err != nil {
		return nil, util.NewNewtError("Mapfile failed: " + err.Error())
	}

	var symName string = ""

	globalMemSections = make(map[string]*MemSection)
	pkgSizes := make(map[string]*PkgSize)
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		switch state {
		case 0:
			if strings.Contains(scanner.Text(), "Memory Configuration") {
				state = 1
			}
		case 1:
			if strings.Contains(scanner.Text(), "Origin") {
				state = 2
			}
		case 2:
			if strings.Contains(scanner.Text(), "*default*") {
				state = 3
				continue
			}
			array := strings.Fields(scanner.Text())
			offset, err := strconv.ParseUint(array[1], 0, 64)
			if err != nil {
				return nil, util.NewNewtError("Can't parse mem info")
			}
			size, err := strconv.ParseUint(array[2], 0, 64)
			if err != nil {
				return nil, util.NewNewtError("Can't parse mem info")
			}
			globalMemSections[array[0]] = MakeMemSection(array[0], offset,
				size)
		case 3:
			if strings.Contains(scanner.Text(),
				"Linker script and memory map") {
				state = 4
			}
		case 4:
			var addrStr string = ""
			var sizeStr string = ""
			var srcFile string = ""

			if strings.Contains(scanner.Text(), "/DISCARD/") ||
				strings.HasPrefix(scanner.Text(), "OUTPUT(") {
				/*
				 * After this there is only discarded symbols
				 */
				state = 5
				continue
			}

			array := strings.Fields(scanner.Text())

			switch len(array) {
			case 1:
				/*
				 * section name on it's own, e.g.
				 * *(.text*)
				 *
				 * section name + symbol name, e.g.
				 * .text.Reset_Handler
				 *
				 * ignore these for now
				 */
				symName = array[0]
				continue
			case 2:
				/*
				 * Either stuff from beginning to first useful data e.g.
				 * END GROUP
				 *
				 * or address of symbol + symbol name, e.g.
				 * 0x00000000080002c8                SystemInit
				 *
				 * or section names with multiple input things, e.g.
				 * *(.ARM.extab* .gnu.linkonce.armextab.*)
				 *
				 * or space set aside in linker script e.g.
				 * 0x0000000020002e80      0x400
				 * (that's the initial stack)
				 *
				 * ignore these for now
				 */
				continue
			case 3:
				/*
				 * address, size, and name of file, e.g.
				 * 0x000000000800bb04     0x1050 /Users/marko/foo/tadpole/hw//mcu/stm/stm32f3xx/bin/blinky_f3/libstm32f3xx.a(stm32f30x_syscfg.o)
				 *
				 * padding, or empty areas defined in linker script:
				 * *fill*         0x000000000800cb71        0x3
				 *
				 * output section name, location, size, e.g.:
				 * .bss            0x0000000020000ab0     0x23d0
				 */
				/*
				 * Record addr, size and name to find library.
				 */
				if array[0] == "*fill*" {
					addrStr = array[1]
					sizeStr = array[2]
					srcFile = array[0]
					symName = array[0]
				} else {
					addrStr = array[0]
					sizeStr = array[1]
					srcFile = array[2]
				}
			case 4:
				/*
				 * section, address, size, name of file, e.g.
				 * COMMON         0x0000000020002d28        0x8 /Users/marko/foo/tadpole/libs//os/bin/blinky_f3/libos.a(os_arch_arm.o)
				 *
				 * linker script symbol definitions:
				 * 0x0000000020002e80                _ebss = .
				 *
				 * crud, e.g.:
				 * 0x8 (size before relaxing)
				 */
				symName = array[0]
				addrStr = array[1]
				sizeStr = array[2]
				srcFile = array[3]
			default:
				continue
			}
			addr, err := strconv.ParseUint(addrStr, 0, 64)
			if err != nil {
				continue
			}
			size, err := strconv.ParseUint(sizeStr, 0, 64)
			if err != nil {
				continue
			}
			if size == 0 {
				continue
			}

			// srcFile might be : mylib.a(object_file.o) or object_file.o
			tmpStrArr := strings.Split(srcFile, "(")
			srcLib := tmpStrArr[0]
			objName := ""
			if srcLib != "*fill*" {
				if len(tmpStrArr) > 1 {
					tmpStrArr = strings.Split(tmpStrArr[1], ")")
					objName = tmpStrArr[0]
				} else {
					objName = filepath.Base(tmpStrArr[0])
				}
			}
			tmpStrArr = strings.Split(symName, ".")
			if len(tmpStrArr) > 2 {
				if tmpStrArr[1] == "rodata" && tmpStrArr[2] == "str1" {
					symName = ".rodata.str1"
				} else {
					symName = tmpStrArr[2]
				}
			}
			pkgSize := pkgSizes[srcLib]
			if pkgSize == nil {
				pkgSize = MakePkgSize(srcLib)
				pkgSizes[srcLib] = pkgSize
			}
			pkgSize.addSymSize(symName, objName, uint32(size), addr)
			symName = ".unknown"
		default:
		}
	}
	file.Close()
	for name, section := range globalMemSections {
		util.StatusMessage(util.VERBOSITY_VERBOSE, "Mem %s: 0x%x-0x%x\n",
			name, section.Offset, section.EndOff)
	}

	return pkgSizes, nil
}

/*
 * Return a printable string containing size data for the libraries
 */
func PrintSizes(libs map[string]*PkgSize) error {
	/*
	 * Order sections by offset, and display lib sizes in that order.
	 */
	memSections := make(MemSectionArray, len(globalMemSections))
	var i int = 0
	for _, sec := range globalMemSections {
		memSections[i] = sec
		i++
	}
	sort.Sort(memSections)

	/*
	 * Order libraries by name, and display them in that order.
	 */
	pkgSizes := make(PkgSizeArray, len(libs))
	i = 0
	for _, es := range libs {
		pkgSizes[i] = es
		i++
	}
	sort.Sort(pkgSizes)

	for _, sec := range memSections {
		fmt.Printf("%7s ", sec.Name)
	}
	fmt.Printf("\n")
	for _, es := range pkgSizes {
		for i := 0; i < len(memSections); i++ {
			fmt.Printf("%7d ", es.Sizes[memSections[i].Name])
		}
		fmt.Printf("%s\n", filepath.Base(es.Name))
	}

	return nil
}

func (t *TargetBuilder) Size() error {

	err := t.PrepBuild()

	if err != nil {
		return err
	}

	fmt.Printf("Size of Application Image: %s\n", t.AppBuilder.buildName)
	err = t.AppBuilder.Size()

	if err == nil {
		if t.LoaderBuilder != nil {
			fmt.Printf("Size of Loader Image: %s\n", t.LoaderBuilder.buildName)
			err = t.LoaderBuilder.Size()
		}
	}

	return err
}

func (b *Builder) FindPkgNameByArName(arName string) string {
	for rpkg, bpkg := range b.PkgMap {
		if b.ArchivePath(bpkg) == arName {
			return rpkg.Lpkg.FullName()
		}
	}
	return filepath.Base(arName)
}

func (b *Builder) PkgSizes() (*image.ImageManifestSizeCollector, error) {
	if b.appPkg == nil {
		return nil, util.NewNewtError("app package not specified for this target")
	}

	if b.targetBuilder.bspPkg.Arch == "sim" {
		return nil, util.NewNewtError("'newt size' not supported for sim targets")
	}
	mapFile := b.AppElfPath() + ".map"

	libs, err := ParseMapFileSizes(mapFile)
	if err != nil {
		return nil, err
	}

	/*
	 * Order libraries by name.
	 */
	pkgSizes := make(PkgSizeArray, len(libs))
	i := 0
	for _, es := range libs {
		pkgSizes[i] = es
		i++
	}
	sort.Sort(pkgSizes)

	c := image.NewImageManifestSizeCollector()
	for _, es := range pkgSizes {
		p := c.AddPkg(b.FindPkgNameByArName(es.Name))

		/*
		 * Order symbols by name.
		 */
		symbols := make(SymbolDataArray, len(es.Syms))
		i := 0
		for _, sym := range es.Syms {
			symbols[i] = sym
			i++
		}
		sort.Sort(symbols)
		for _, sym := range symbols {
			for area, areaSz := range sym.Sizes {
				if areaSz != 0 {
					p.AddSymbol(sym.ObjName, sym.Name, area, areaSz)
				}
			}
		}
	}

	return c, nil
}

func (b *Builder) Size() error {
	if b.appPkg == nil {
		return util.NewNewtError("app package not specified for this target")
	}

	err := b.targetBuilder.PrepBuild()
	if err != nil {
		return err
	}
	if b.targetBuilder.bspPkg.Arch == "sim" {
		fmt.Println("'newt size' not supported for sim targets.")
		return nil
	}
	mapFile := b.AppElfPath() + ".map"

	pkgSizes, err := ParseMapFileSizes(mapFile)
	if err != nil {
		return err
	}
	err = PrintSizes(pkgSizes)
	if err != nil {
		return err
	}

	c, err := b.newCompiler(b.appPkg, b.FileBinDir(b.AppElfPath()))
	if err != nil {
		return err
	}

	fmt.Printf("\nobjsize\n")
	output, err := c.PrintSize(b.AppElfPath())
	if err != nil {
		return err
	}
	fmt.Printf("%s", output)

	return nil
}

func (t *TargetBuilder) SizeReport(sectionName string) error {

	err := t.PrepBuild()

	if err != nil {
		return err
	}

	fmt.Printf("Size of Application Image: %s\n", t.AppBuilder.buildName)
	err = t.AppBuilder.SizeReport(sectionName)

	if err == nil {
		if t.LoaderBuilder != nil {
			fmt.Printf("Size of Loader Image: %s\n", t.LoaderBuilder.buildName)
			err = t.LoaderBuilder.SizeReport(sectionName)
		}
	}

	return err
}

func (b *Builder) SizeReport(sectionName string) error {
	srcBase := interfaces.GetProject().Path() + "/"

	err := SizeReport(b.AppElfPath(), srcBase, sectionName)
	if err != nil {
		return util.NewNewtError(err.Error())
	}
	return nil
}
