// 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
	columnnumber := 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 3:
			// filename:line:column
			if col, err := strconv.Atoi(split[2]); err == nil {
				columnnumber = col
			}
			fallthrough
		case 2:
			// filename:line
			if line, err := strconv.Atoi(split[1]); err == nil {
				linenumber = line
			}
			fallthrough
		case 1:
			// filename
			fileline = split[0]
		default:
			// Unrecognized, ignore
		}
	}

	return plugin.Frame{Func: funcname, File: fileline, Line: linenumber, Column: columnnumber}, 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
}
