// 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 symbolz symbolizes a profile using the output from the symbolz
// service.
package symbolz

import (
	"bytes"
	"fmt"
	"io"
	"net/url"
	"path"
	"regexp"
	"strconv"
	"strings"

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

var (
	symbolzRE = regexp.MustCompile(`(0x[[:xdigit:]]+)\s+(.*)`)
)

// Symbolize symbolizes profile p by parsing data returned by a
// symbolz handler. syms receives the symbolz query (hex addresses
// separated by '+') and returns the symbolz output in a string. It
// symbolizes all locations based on their addresses, regardless of
// mapping.
func Symbolize(sources plugin.MappingSources, syms func(string, string) ([]byte, error), p *profile.Profile, ui plugin.UI) error {
	for _, m := range p.Mapping {
		if m.HasFunctions {
			continue
		}
		mappingSources := sources[m.File]
		if m.BuildID != "" {
			mappingSources = append(mappingSources, sources[m.BuildID]...)
		}
		for _, source := range mappingSources {
			if symz := symbolz(source.Source); symz != "" {
				if err := symbolizeMapping(symz, int64(source.Start)-int64(m.Start), syms, m, p); err != nil {
					return err
				}
				m.HasFunctions = true
				break
			}
		}
	}

	return nil
}

// symbolz returns the corresponding symbolz source for a profile URL.
func symbolz(source string) string {
	if url, err := url.Parse(source); err == nil && url.Host != "" {
		if strings.Contains(url.Path, "/") {
			if dir := path.Dir(url.Path); dir == "/debug/pprof" {
				// For Go language profile handlers in net/http/pprof package.
				url.Path = "/debug/pprof/symbol"
			} else {
				url.Path = "/symbolz"
			}
			url.RawQuery = ""
			return url.String()
		}
	}

	return ""
}

// symbolizeMapping symbolizes locations belonging to a Mapping by querying
// a symbolz handler. An offset is applied to all addresses to take care of
// normalization occured for merged Mappings.
func symbolizeMapping(source string, offset int64, syms func(string, string) ([]byte, error), m *profile.Mapping, p *profile.Profile) error {
	// Construct query of addresses to symbolize.
	var a []string
	for _, l := range p.Location {
		if l.Mapping == m && l.Address != 0 && len(l.Line) == 0 {
			// Compensate for normalization.
			addr := int64(l.Address) + offset
			if addr < 0 {
				return fmt.Errorf("unexpected negative adjusted address, mapping %v source %d, offset %d", l.Mapping, l.Address, offset)
			}
			a = append(a, fmt.Sprintf("%#x", addr))
		}
	}

	if len(a) == 0 {
		// No addresses to symbolize.
		return nil
	}

	lines := make(map[uint64]profile.Line)
	functions := make(map[string]*profile.Function)

	b, err := syms(source, strings.Join(a, "+"))
	if err != nil {
		return err
	}

	buf := bytes.NewBuffer(b)
	for {
		l, err := buf.ReadString('\n')

		if err != nil {
			if err == io.EOF {
				break
			}
			return err
		}

		if symbol := symbolzRE.FindStringSubmatch(l); len(symbol) == 3 {
			addr, err := strconv.ParseInt(symbol[1], 0, 64)
			if err != nil {
				return fmt.Errorf("unexpected parse failure %s: %v", symbol[1], err)
			}
			if addr < 0 {
				return fmt.Errorf("unexpected negative adjusted address, source %s, offset %d", symbol[1], offset)
			}
			// Reapply offset expected by the profile.
			addr -= offset

			name := symbol[2]
			fn := functions[name]
			if fn == nil {
				fn = &profile.Function{
					ID:         uint64(len(p.Function) + 1),
					Name:       name,
					SystemName: name,
				}
				functions[name] = fn
				p.Function = append(p.Function, fn)
			}

			lines[uint64(addr)] = profile.Line{Function: fn}
		}
	}

	for _, l := range p.Location {
		if l.Mapping != m {
			continue
		}
		if line, ok := lines[l.Address]; ok {
			l.Line = []profile.Line{line}
		}
	}

	return nil
}
