// Copyright 2014 Google Inc. All Rights Reserved.
//
// Licensed 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 binutils

import (
	"bufio"
	"fmt"
	"io"
	"os/exec"
	"strconv"
	"strings"
	"sync"

	"github.com/google/pprof/internal/plugin"
)

const (
	defaultLLVMSymbolizer = "llvm-symbolizer"
)

// llvmSymbolizer is a connection to an llvm-symbolizer command for
// obtaining address and line number information from a binary.
type llvmSymbolizer struct {
	sync.Mutex
	filename string
	rw       lineReaderWriter
	base     uint64
}

type llvmSymbolizerJob struct {
	cmd *exec.Cmd
	in  io.WriteCloser
	out *bufio.Reader
	// llvm-symbolizer requires the symbol type, CODE or DATA, for symbolization.
	symType string
}

func (a *llvmSymbolizerJob) write(s string) error {
	_, err := fmt.Fprintln(a.in, a.symType, s)
	return err
}

func (a *llvmSymbolizerJob) readLine() (string, error) {
	s, err := a.out.ReadString('\n')
	if err != nil {
		return "", err
	}
	return strings.TrimSpace(s), nil
}

// close releases any resources used by the llvmSymbolizer object.
func (a *llvmSymbolizerJob) close() {
	a.in.Close()
	a.cmd.Wait()
}

// newLlvmSymbolizer starts the given llvmSymbolizer command reporting
// information about the given executable file. If file is a shared
// library, base should be the address at which it was mapped in the
// program under consideration.
func newLLVMSymbolizer(cmd, file string, base uint64, isData bool) (*llvmSymbolizer, error) {
	if cmd == "" {
		cmd = defaultLLVMSymbolizer
	}

	j := &llvmSymbolizerJob{
		cmd:     exec.Command(cmd, "-inlining", "-demangle=false"),
		symType: "CODE",
	}
	if isData {
		j.symType = "DATA"
	}

	var err error
	if j.in, err = j.cmd.StdinPipe(); err != nil {
		return nil, err
	}

	outPipe, err := j.cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}

	j.out = bufio.NewReader(outPipe)
	if err := j.cmd.Start(); err != nil {
		return nil, err
	}

	a := &llvmSymbolizer{
		filename: file,
		rw:       j,
		base:     base,
	}

	return a, nil
}

// readFrame parses the llvm-symbolizer output for a single address. It
// returns a populated plugin.Frame and whether it has reached the end of the
// data.
func (d *llvmSymbolizer) readFrame() (plugin.Frame, bool) {
	funcname, err := d.rw.readLine()
	if err != nil {
		return plugin.Frame{}, true
	}

	switch funcname {
	case "":
		return plugin.Frame{}, true
	case "??":
		funcname = ""
	}

	fileline, err := d.rw.readLine()
	if err != nil {
		return plugin.Frame{Func: funcname}, true
	}

	linenumber := 0
	// The llvm-symbolizer outputs the <file_name>:<line_number>:<column_number>.
	// When it cannot identify the source code location, it outputs "??:0:0".
	// Older versions output just the filename and line number, so we check for
	// both conditions here.
	if fileline == "??:0" || fileline == "??:0:0" {
		fileline = ""
	} else {
		switch split := strings.Split(fileline, ":"); len(split) {
		case 1:
			// filename
			fileline = split[0]
		case 2, 3:
			// filename:line , or
			// filename:line:disc , or
			fileline = split[0]
			if line, err := strconv.Atoi(split[1]); err == nil {
				linenumber = line
			}
		default:
			// Unrecognized, ignore
		}
	}

	return plugin.Frame{Func: funcname, File: fileline, Line: linenumber}, false
}

// addrInfo returns the stack frame information for a specific program
// address. It returns nil if the address could not be identified.
func (d *llvmSymbolizer) addrInfo(addr uint64) ([]plugin.Frame, error) {
	d.Lock()
	defer d.Unlock()

	if err := d.rw.write(fmt.Sprintf("%s 0x%x", d.filename, addr-d.base)); err != nil {
		return nil, err
	}

	var stack []plugin.Frame
	for {
		frame, end := d.readFrame()
		if end {
			break
		}

		if frame != (plugin.Frame{}) {
			stack = append(stack, frame)
		}
	}

	return stack, nil
}
