// Copyright 2014 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 local provides access to a local program.
package local // import "golang.org/x/debug/ogle/program/local"

import (
	"golang.org/x/debug/ogle/program"
	"golang.org/x/debug/ogle/program/proxyrpc"
	"golang.org/x/debug/ogle/program/server"
)

var _ program.Program = (*Local)(nil)
var _ program.File = (*File)(nil)

// Local implements the interface program.Program.
// Through that interface it provides access to a program being debugged.
type Local struct {
	s *server.Server
}

// New creates a new program from the specified file.
// The program can then be started by the Run method.
func New(textFile string) (*Local, error) {
	s, err := server.New(textFile)
	return &Local{s: s}, err
}

func (l *Local) Open(name string, mode string) (program.File, error) {
	req := proxyrpc.OpenRequest{
		Name: name,
		Mode: mode,
	}
	var resp proxyrpc.OpenResponse
	err := l.s.Open(&req, &resp)
	if err != nil {
		return nil, err
	}
	f := &File{
		prog: l,
		fd:   resp.FD,
	}
	return f, nil
}

func (l *Local) Run(args ...string) (program.Status, error) {
	req := proxyrpc.RunRequest{args}
	var resp proxyrpc.RunResponse
	err := l.s.Run(&req, &resp)
	if err != nil {
		return program.Status{}, err
	}
	return resp.Status, nil
}

func (l *Local) Stop() (program.Status, error) {
	panic("unimplemented")
}

func (l *Local) Resume() (program.Status, error) {
	req := proxyrpc.ResumeRequest{}
	var resp proxyrpc.ResumeResponse
	err := l.s.Resume(&req, &resp)
	if err != nil {
		return program.Status{}, err
	}
	return resp.Status, nil
}

func (l *Local) Kill() (program.Status, error) {
	panic("unimplemented")
}

func (l *Local) Breakpoint(address uint64) ([]uint64, error) {
	req := proxyrpc.BreakpointRequest{address}
	var resp proxyrpc.BreakpointResponse
	err := l.s.Breakpoint(&req, &resp)
	return resp.PCs, err
}

func (l *Local) BreakpointAtFunction(name string) ([]uint64, error) {
	req := proxyrpc.BreakpointAtFunctionRequest{name}
	var resp proxyrpc.BreakpointResponse
	err := l.s.BreakpointAtFunction(&req, &resp)
	return resp.PCs, err
}

func (l *Local) BreakpointAtLine(file string, line uint64) ([]uint64, error) {
	req := proxyrpc.BreakpointAtLineRequest{file, line}
	var resp proxyrpc.BreakpointResponse
	err := l.s.BreakpointAtLine(&req, &resp)
	return resp.PCs, err
}

func (l *Local) DeleteBreakpoints(pcs []uint64) error {
	req := proxyrpc.DeleteBreakpointsRequest{PCs: pcs}
	var resp proxyrpc.DeleteBreakpointsResponse
	return l.s.DeleteBreakpoints(&req, &resp)
}

func (l *Local) Eval(expr string) ([]string, error) {
	req := proxyrpc.EvalRequest{
		Expr: expr,
	}
	var resp proxyrpc.EvalResponse
	err := l.s.Eval(&req, &resp)
	return resp.Result, err
}

func (l *Local) Frames(count int) ([]program.Frame, error) {
	req := proxyrpc.FramesRequest{
		Count: count,
	}
	var resp proxyrpc.FramesResponse
	err := l.s.Frames(&req, &resp)
	return resp.Frames, err
}

func (l *Local) VarByName(name string) (program.Var, error) {
	req := proxyrpc.VarByNameRequest{Name: name}
	var resp proxyrpc.VarByNameResponse
	err := l.s.VarByName(&req, &resp)
	return resp.Var, err
}

func (l *Local) Value(v program.Var) (program.Value, error) {
	req := proxyrpc.ValueRequest{Var: v}
	var resp proxyrpc.ValueResponse
	err := l.s.Value(&req, &resp)
	return resp.Value, err
}

func (l *Local) MapElement(m program.Map, index uint64) (program.Var, program.Var, error) {
	req := proxyrpc.MapElementRequest{Map: m, Index: index}
	var resp proxyrpc.MapElementResponse
	err := l.s.MapElement(&req, &resp)
	return resp.Key, resp.Value, err
}

// File implements the program.File interface, providing access
// to file-like resources associated with the target program.
type File struct {
	prog *Local // The Program associated with the file.
	fd   int    // File descriptor.
}

func (f *File) ReadAt(p []byte, offset int64) (int, error) {
	req := proxyrpc.ReadAtRequest{
		FD:     f.fd,
		Len:    len(p),
		Offset: offset,
	}
	var resp proxyrpc.ReadAtResponse
	err := f.prog.s.ReadAt(&req, &resp)
	return copy(p, resp.Data), err
}

func (f *File) WriteAt(p []byte, offset int64) (int, error) {
	panic("unimplemented")
}

func (f *File) Close() error {
	req := proxyrpc.CloseRequest{
		FD: f.fd,
	}
	var resp proxyrpc.CloseResponse
	err := f.prog.s.Close(&req, &resp)
	return err
}
