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

// Parsing of Plan 9 a.out executables.

package objfile

import (
	"debug/dwarf"
	"debug/plan9obj"
	"errors"
	"fmt"
	"io"
	"slices"
	"sort"
)

var validSymType = map[rune]bool{
	'T': true,
	't': true,
	'D': true,
	'd': true,
	'B': true,
	'b': true,
}

type plan9File struct {
	plan9 *plan9obj.File
}

func openPlan9(r io.ReaderAt) (rawFile, error) {
	f, err := plan9obj.NewFile(r)
	if err != nil {
		return nil, err
	}
	return &plan9File{f}, nil
}

func (f *plan9File) symbols() ([]Sym, error) {
	plan9Syms, err := f.plan9.Symbols()
	if err != nil {
		return nil, err
	}

	// Build sorted list of addresses of all symbols.
	// We infer the size of a symbol by looking at where the next symbol begins.
	var addrs []uint64
	for _, s := range plan9Syms {
		if !validSymType[s.Type] {
			continue
		}
		addrs = append(addrs, s.Value)
	}
	slices.Sort(addrs)

	var syms []Sym

	for _, s := range plan9Syms {
		if !validSymType[s.Type] {
			continue
		}
		sym := Sym{Addr: s.Value, Name: s.Name, Code: s.Type}
		i := sort.Search(len(addrs), func(x int) bool { return addrs[x] > s.Value })
		if i < len(addrs) {
			sym.Size = int64(addrs[i] - s.Value)
		}
		syms = append(syms, sym)
	}

	return syms, nil
}

func (f *plan9File) pcln() (textStart uint64, pclntab []byte, err error) {
	textStart = f.plan9.LoadAddress + f.plan9.HdrSize
	if pclntab, err = loadPlan9Table(f.plan9, "runtime.pclntab", "runtime.epclntab"); err != nil {
		// We didn't find the symbols, so look for the names used in 1.3 and earlier.
		// TODO: Remove code looking for the old symbols when we no longer care about 1.3.
		var err2 error
		if pclntab, err2 = loadPlan9Table(f.plan9, "pclntab", "epclntab"); err2 != nil {
			return 0, nil, err
		}
	}
	return textStart, pclntab, nil
}

func (f *plan9File) text() (textStart uint64, text []byte, err error) {
	sect := f.plan9.Section("text")
	if sect == nil {
		return 0, nil, fmt.Errorf("text section not found")
	}
	textStart = f.plan9.LoadAddress + f.plan9.HdrSize
	text, err = sect.Data()
	return
}

func findPlan9Symbol(f *plan9obj.File, name string) (*plan9obj.Sym, error) {
	syms, err := f.Symbols()
	if err != nil {
		return nil, err
	}
	for _, s := range syms {
		if s.Name != name {
			continue
		}
		return &s, nil
	}
	return nil, fmt.Errorf("no %s symbol found", name)
}

func loadPlan9Table(f *plan9obj.File, sname, ename string) ([]byte, error) {
	ssym, err := findPlan9Symbol(f, sname)
	if err != nil {
		return nil, err
	}
	esym, err := findPlan9Symbol(f, ename)
	if err != nil {
		return nil, err
	}
	sect := f.Section("text")
	if sect == nil {
		return nil, err
	}
	data, err := sect.Data()
	if err != nil {
		return nil, err
	}
	textStart := f.LoadAddress + f.HdrSize
	return data[ssym.Value-textStart : esym.Value-textStart], nil
}

func (f *plan9File) goarch() string {
	switch f.plan9.Magic {
	case plan9obj.Magic386:
		return "386"
	case plan9obj.MagicAMD64:
		return "amd64"
	case plan9obj.MagicARM:
		return "arm"
	}
	return ""
}

func (f *plan9File) loadAddress() (uint64, error) {
	return 0, fmt.Errorf("unknown load address")
}

func (f *plan9File) dwarf() (*dwarf.Data, error) {
	return nil, errors.New("no DWARF data in Plan 9 file")
}
