// Copyright 2016 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 runtime_test

import (
	"internal/testenv"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
)

var lldbPath string

func checkLldbPython(t *testing.T) {
	cmd := exec.Command("lldb", "-P")
	out, err := cmd.CombinedOutput()
	if err != nil {
		t.Skipf("skipping due to issue running lldb: %v\n%s", err, out)
	}
	lldbPath = strings.TrimSpace(string(out))

	cmd = exec.Command("/usr/bin/python2.7", "-c", "import sys;sys.path.append(sys.argv[1]);import lldb; print('go lldb python support')", lldbPath)
	out, err = cmd.CombinedOutput()

	if err != nil {
		t.Skipf("skipping due to issue running python: %v\n%s", err, out)
	}
	if string(out) != "go lldb python support\n" {
		t.Skipf("skipping due to lack of python lldb support: %s", out)
	}

	if runtime.GOOS == "darwin" {
		// Try to see if we have debugging permissions.
		cmd = exec.Command("/usr/sbin/DevToolsSecurity", "-status")
		out, err = cmd.CombinedOutput()
		if err != nil {
			t.Skipf("DevToolsSecurity failed: %v", err)
		} else if !strings.Contains(string(out), "enabled") {
			t.Skip(string(out))
		}
		cmd = exec.Command("/usr/bin/groups")
		out, err = cmd.CombinedOutput()
		if err != nil {
			t.Skipf("groups failed: %v", err)
		} else if !strings.Contains(string(out), "_developer") {
			t.Skip("Not in _developer group")
		}
	}
}

const lldbHelloSource = `
package main
import "fmt"
func main() {
	mapvar := make(map[string]string,5)
	mapvar["abc"] = "def"
	mapvar["ghi"] = "jkl"
	intvar := 42
	ptrvar := &intvar
	fmt.Println("hi") // line 10
	_ = ptrvar
}
`

const lldbScriptSource = `
import sys
sys.path.append(sys.argv[1])
import lldb
import os

TIMEOUT_SECS = 5

debugger = lldb.SBDebugger.Create()
debugger.SetAsync(True)
target = debugger.CreateTargetWithFileAndArch("a.exe", None)
if target:
  print "Created target"
  main_bp = target.BreakpointCreateByLocation("main.go", 10)
  if main_bp:
    print "Created breakpoint"
  process = target.LaunchSimple(None, None, os.getcwd())
  if process:
    print "Process launched"
    listener = debugger.GetListener()
    process.broadcaster.AddListener(listener, lldb.SBProcess.eBroadcastBitStateChanged)
    while True:
      event = lldb.SBEvent()
      if listener.WaitForEvent(TIMEOUT_SECS, event):
        if lldb.SBProcess.GetRestartedFromEvent(event):
          continue
        state = process.GetState()
        if state in [lldb.eStateUnloaded, lldb.eStateLaunching, lldb.eStateRunning]:
          continue
      else:
        print "Timeout launching"
      break
    if state == lldb.eStateStopped:
      for t in process.threads:
        if t.GetStopReason() == lldb.eStopReasonBreakpoint:
          print "Hit breakpoint"
          frame = t.GetFrameAtIndex(0)
          if frame:
            if frame.line_entry:
              print "Stopped at %s:%d" % (frame.line_entry.file.basename, frame.line_entry.line)
            if frame.function:
              print "Stopped in %s" % (frame.function.name,)
            var = frame.FindVariable('intvar')
            if var:
              print "intvar = %s" % (var.GetValue(),)
            else:
              print "no intvar"
    else:
      print "Process state", state
    process.Destroy()
else:
  print "Failed to create target a.exe"

lldb.SBDebugger.Destroy(debugger)
sys.exit()
`

const expectedLldbOutput = `Created target
Created breakpoint
Process launched
Hit breakpoint
Stopped at main.go:10
Stopped in main.main
intvar = 42
`

func TestLldbPython(t *testing.T) {
	testenv.MustHaveGoBuild(t)
	if final := os.Getenv("GOROOT_FINAL"); final != "" && runtime.GOROOT() != final {
		t.Skip("gdb test can fail with GOROOT_FINAL pending")
	}
	testenv.SkipFlaky(t, 31188)

	checkLldbPython(t)

	dir, err := ioutil.TempDir("", "go-build")
	if err != nil {
		t.Fatalf("failed to create temp directory: %v", err)
	}
	defer os.RemoveAll(dir)

	src := filepath.Join(dir, "main.go")
	err = ioutil.WriteFile(src, []byte(lldbHelloSource), 0644)
	if err != nil {
		t.Fatalf("failed to create src file: %v", err)
	}

	mod := filepath.Join(dir, "go.mod")
	err = ioutil.WriteFile(mod, []byte("module lldbtest"), 0644)
	if err != nil {
		t.Fatalf("failed to create mod file: %v", err)
	}

	// As of 2018-07-17, lldb doesn't support compressed DWARF, so
	// disable it for this test.
	cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags=all=-N -l", "-ldflags=-compressdwarf=false", "-o", "a.exe")
	cmd.Dir = dir
	cmd.Env = append(os.Environ(), "GOPATH=") // issue 31100
	out, err := cmd.CombinedOutput()
	if err != nil {
		t.Fatalf("building source %v\n%s", err, out)
	}

	src = filepath.Join(dir, "script.py")
	err = ioutil.WriteFile(src, []byte(lldbScriptSource), 0755)
	if err != nil {
		t.Fatalf("failed to create script: %v", err)
	}

	cmd = exec.Command("/usr/bin/python2.7", "script.py", lldbPath)
	cmd.Dir = dir
	got, _ := cmd.CombinedOutput()

	if string(got) != expectedLldbOutput {
		if strings.Contains(string(got), "Timeout launching") {
			t.Skip("Timeout launching")
		}
		t.Fatalf("Unexpected lldb output:\n%s", got)
	}
}
