// Copyright 2015 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 buildlet

import (
	"context"
	"errors"
	"fmt"
	"io"
	"net"
	"net/http"
	"os"
	"strings"

	"golang.org/x/oauth2"
)

// Client is an interface that represent the methods exposed by client. The
// fake buildlet client should be used instead of client when testing things that
// use the client interface.
type Client interface {
	AddCloseFunc(fn func())
	Close() error
	ConnectSSH(user, authorizedPubKey string) (net.Conn, error)
	DestroyVM(ts oauth2.TokenSource, proj, zone, instance string) error
	Exec(ctx context.Context, cmd string, opts ExecOpts) (remoteErr, execErr error)
	GCEInstanceName() string
	GetTar(ctx context.Context, dir string) (io.ReadCloser, error)
	IPPort() string
	IsBroken() bool
	ListDir(ctx context.Context, dir string, opts ListDirOpts, fn func(DirEntry)) error
	MarkBroken()
	Name() string
	ProxyRoundTripper() http.RoundTripper
	ProxyTCP(port int) (io.ReadWriteCloser, error)
	Put(ctx context.Context, r io.Reader, path string, mode os.FileMode) error
	PutTar(ctx context.Context, r io.Reader, dir string) error
	PutTarFromURL(ctx context.Context, tarURL, dir string) error
	RemoteName() string
	RemoveAll(ctx context.Context, paths ...string) error
	SetDescription(v string)
	SetDialer(dialer func(context.Context) (net.Conn, error))
	SetGCEInstanceName(v string)
	SetHTTPClient(httpClient *http.Client)
	SetName(name string)
	SetOnHeartbeatFailure(fn func())
	SetReleaseMode(v bool)
	Status(ctx context.Context) (Status, error)
	String() string
	URL() string
	WorkDir(ctx context.Context) (string, error)
}

var errUnimplemented = errors.New("unimplemented function")

var _ Client = (*FakeClient)(nil)

// FakeClient is a fake buildlet client used for testing. Not all functions are implemented.
type FakeClient struct {
	closeFuncs   []func()
	instanceName string
	name         string
}

// AddCloseFunc adds optional extra code to run on close for the fake buildlet.
func (fc *FakeClient) AddCloseFunc(fn func()) {
	fc.closeFuncs = append(fc.closeFuncs, fn)
}

// Close is a fake client closer.
func (fc *FakeClient) Close() error {
	for _, f := range fc.closeFuncs {
		f()
	}
	return nil
}

// ConnectSSH connects to a fake SSH server.
func (fc *FakeClient) ConnectSSH(user, authorizedPubKey string) (net.Conn, error) {
	return nil, errUnimplemented
}

// DestroyVM destroys a fake VM.
func (fc *FakeClient) DestroyVM(ts oauth2.TokenSource, proj, zone, instance string) error {
	return errUnimplemented
}

// Exec fakes the execution.
func (fc *FakeClient) Exec(ctx context.Context, cmd string, opts ExecOpts) (remoteErr, execErr error) {
	if cmd == "" {
		return nil, errors.New("invalid command")
	}
	if opts.Output == nil {
		return nil, nil
	}
	out := []byte("<this is a song that never ends>")
	for it := 0; it < 3; it++ {
		if n, err := opts.Output.Write(out); n != len(out) || err != nil {
			return nil, fmt.Errorf("Output.Write(...) = %d, %q; want %d, no error", n, err, len(out))
		}
	}
	return nil, nil
}

// GCEInstanceName gives the fake instance name.
func (fc *FakeClient) GCEInstanceName() string { return fc.instanceName }

// GetTar gives a vake tar zipped directory.
func (fc *FakeClient) GetTar(ctx context.Context, dir string) (io.ReadCloser, error) {
	return nil, errUnimplemented
}

// IPPort provides a fake ip and port pair.
func (fc *FakeClient) IPPort() string { return "" }

// IsBroken returns a fake broken response.
func (fc *FakeClient) IsBroken() bool { return false }

// ListDir lists a directory on a fake buildlet.
func (fc *FakeClient) ListDir(ctx context.Context, dir string, opts ListDirOpts, fn func(DirEntry)) error {
	if dir == "" || fn == nil {
		errors.New("invalid arguments")
	}
	var lsOutput = `drwxr-xr-x      gocache/
drwxr-xr-x      tmp/`
	lines := strings.Split(lsOutput, "\n")
	for _, line := range lines {
		fn(DirEntry{line: line})
	}
	return nil
}

// MarkBroken marks the fake client as broken.
func (fc *FakeClient) MarkBroken() {}

// Name is the name of the fake client.
func (fc *FakeClient) Name() string { return fc.name }

// ProxyRoundTripper provides a fake proxy.
func (fc *FakeClient) ProxyRoundTripper() http.RoundTripper { return nil }

// ProxyTCP provides a fake proxy.
func (fc *FakeClient) ProxyTCP(port int) (io.ReadWriteCloser, error) { return nil, errUnimplemented }

// Put places a file on a fake buildlet.
func (fc *FakeClient) Put(ctx context.Context, r io.Reader, path string, mode os.FileMode) error {
	// TODO(go.dev/issue/48742) add a file system implementation which would enable proper testing.
	return errUnimplemented
}

// PutTar fakes putting  a tar zipped file on a buildldet.
func (fc *FakeClient) PutTar(ctx context.Context, r io.Reader, dir string) error {
	// TODO(go.dev/issue/48742) add a file system implementation which would enable proper testing.
	return errUnimplemented
}

// PutTarFromURL fakes putting a tar zipped file on a builelt.
func (fc *FakeClient) PutTarFromURL(ctx context.Context, tarURL, dir string) error {
	return nil
}

// RemoteName gives the remote name of the fake buildlet.
func (fc *FakeClient) RemoteName() string { return "" }

// SetDescription sets the description on a fake client.
func (fc *FakeClient) SetDescription(v string) {}

// SetDialer sets the function that creates a new connection to the fake buildlet.
func (fc *FakeClient) SetDialer(dialer func(context.Context) (net.Conn, error)) {}

// SetGCEInstanceName sets the GCE instance name on a fake client.
func (fc *FakeClient) SetGCEInstanceName(v string) {
	fc.instanceName = v
}

// SetHTTPClient sets the HTTP client on a fake client.
func (fc *FakeClient) SetHTTPClient(httpClient *http.Client) {}

// SetName sets the name on a fake client.
func (fc *FakeClient) SetName(name string) {
	fc.name = name
}

// SetOnHeartbeatFailure sets a function to be called when heartbeats against this fake buildlet fail.
func (fc *FakeClient) SetOnHeartbeatFailure(fn func()) {}

// SetReleaseMode sets the release mode on a fake client.
func (fc *FakeClient) SetReleaseMode(v bool) {}

// Status provides a status on the fake client.
func (fc *FakeClient) Status(ctx context.Context) (Status, error) { return Status{}, errUnimplemented }

// String provides a fake string representation of the client.
func (fc *FakeClient) String() string { return "" }

// URL is the URL for a fake buildlet.
func (fc *FakeClient) URL() string { return "" }

// WorkDir is the working directory for the fake buildlet.
func (fc *FakeClient) WorkDir(ctx context.Context) (string, error) { return "", errUnimplemented }

// RemoveAll deletes the provided paths, relative to the work directory for a fake buildlet.
func (fc *FakeClient) RemoveAll(ctx context.Context, paths ...string) error {
	// TODO(go.dev/issue/48742) add a file system implementation which would enable proper testing.
	return nil
}
