// Copyright 2020 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 pkgpath determines the package path used by gccgo/GoLLVM symbols.
// This package is not used for the gc compiler.
package pkgpath

import (
	"bytes"
	"errors"
	"fmt"
	"os"
	"os/exec"
	"strings"
)

// ToSymbolFunc returns a function that may be used to convert a
// package path into a string suitable for use as a symbol.
// cmd is the gccgo/GoLLVM compiler in use, and tmpdir is a temporary
// directory to pass to os.CreateTemp().
// For example, this returns a function that converts "net/http"
// into a string like "net..z2fhttp". The actual string varies for
// different gccgo/GoLLVM versions, which is why this returns a function
// that does the conversion appropriate for the compiler in use.
func ToSymbolFunc(cmd, tmpdir string) (func(string) string, error) {
	// To determine the scheme used by cmd, we compile a small
	// file and examine the assembly code. Older versions of gccgo
	// use a simple mangling scheme where there can be collisions
	// between packages whose paths are different but mangle to
	// the same string. More recent versions use a new mangler
	// that avoids these collisions.
	const filepat = "*_gccgo_manglechck.go"
	f, err := os.CreateTemp(tmpdir, filepat)
	if err != nil {
		return nil, err
	}
	gofilename := f.Name()
	f.Close()
	defer os.Remove(gofilename)

	if err := os.WriteFile(gofilename, []byte(mangleCheckCode), 0644); err != nil {
		return nil, err
	}

	command := exec.Command(cmd, "-S", "-o", "-", gofilename)
	buf, err := command.Output()
	if err != nil {
		return nil, err
	}

	// Original mangling: go.l__ufer.Run
	// Mangling v2: go.l..u00e4ufer.Run
	// Mangling v3: go_0l_u00e4ufer.Run
	if bytes.Contains(buf, []byte("go_0l_u00e4ufer.Run")) {
		return toSymbolV3, nil
	} else if bytes.Contains(buf, []byte("go.l..u00e4ufer.Run")) {
		return toSymbolV2, nil
	} else if bytes.Contains(buf, []byte("go.l__ufer.Run")) {
		return toSymbolV1, nil
	} else {
		return nil, errors.New(cmd + ": unrecognized mangling scheme")
	}
}

// mangleCheckCode is the package we compile to determine the mangling scheme.
const mangleCheckCode = `
package läufer
func Run(x int) int {
  return 1
}
`

// toSymbolV1 converts a package path using the original mangling scheme.
func toSymbolV1(ppath string) string {
	clean := func(r rune) rune {
		switch {
		case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',
			'0' <= r && r <= '9':
			return r
		}
		return '_'
	}
	return strings.Map(clean, ppath)
}

// toSymbolV2 converts a package path using the second mangling scheme.
func toSymbolV2(ppath string) string {
	var bsl strings.Builder
	changed := false
	for _, c := range ppath {
		if ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') || c == '_' {
			bsl.WriteByte(byte(c))
			continue
		}
		var enc string
		switch {
		case c == '.':
			enc = ".x2e"
		case c < 0x80:
			enc = fmt.Sprintf("..z%02x", c)
		case c < 0x10000:
			enc = fmt.Sprintf("..u%04x", c)
		default:
			enc = fmt.Sprintf("..U%08x", c)
		}
		bsl.WriteString(enc)
		changed = true
	}
	if !changed {
		return ppath
	}
	return bsl.String()
}

// v3UnderscoreCodes maps from a character that supports an underscore
// encoding to the underscore encoding character.
var v3UnderscoreCodes = map[byte]byte{
	'_': '_',
	'.': '0',
	'/': '1',
	'*': '2',
	',': '3',
	'{': '4',
	'}': '5',
	'[': '6',
	']': '7',
	'(': '8',
	')': '9',
	'"': 'a',
	' ': 'b',
	';': 'c',
}

// toSymbolV3 converts a package path using the third mangling scheme.
func toSymbolV3(ppath string) string {
	var bsl strings.Builder
	changed := false
	for _, c := range ppath {
		if ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') {
			bsl.WriteByte(byte(c))
			continue
		}

		if c < 0x80 {
			if u, ok := v3UnderscoreCodes[byte(c)]; ok {
				bsl.WriteByte('_')
				bsl.WriteByte(u)
				changed = true
				continue
			}
		}

		var enc string
		switch {
		case c < 0x80:
			enc = fmt.Sprintf("_x%02x", c)
		case c < 0x10000:
			enc = fmt.Sprintf("_u%04x", c)
		default:
			enc = fmt.Sprintf("_U%08x", c)
		}
		bsl.WriteString(enc)
		changed = true
	}
	if !changed {
		return ppath
	}
	return bsl.String()
}
