package logger // import "github.com/docker/docker/daemon/logger"

import (
	"fmt"
	"io"
	"os"
	"path/filepath"

	"github.com/docker/docker/api/types/plugins/logdriver"
	"github.com/docker/docker/errdefs"
	getter "github.com/docker/docker/pkg/plugingetter"
	"github.com/docker/docker/pkg/plugins"
	"github.com/docker/docker/pkg/stringid"
	"github.com/pkg/errors"
)

var pluginGetter getter.PluginGetter

const extName = "LogDriver"

// logPlugin defines the available functions that logging plugins must implement.
type logPlugin interface {
	StartLogging(streamPath string, info Info) (err error)
	StopLogging(streamPath string) (err error)
	Capabilities() (cap Capability, err error)
	ReadLogs(info Info, config ReadConfig) (stream io.ReadCloser, err error)
}

// RegisterPluginGetter sets the plugingetter
func RegisterPluginGetter(plugingetter getter.PluginGetter) {
	pluginGetter = plugingetter
}

// GetDriver returns a logging driver by its name.
// If the driver is empty, it looks for the local driver.
func getPlugin(name string, mode int) (Creator, error) {
	p, err := pluginGetter.Get(name, extName, mode)
	if err != nil {
		return nil, fmt.Errorf("error looking up logging plugin %s: %v", name, err)
	}

	client, err := makePluginClient(p)
	if err != nil {
		return nil, err
	}
	return makePluginCreator(name, client, p.ScopedPath), nil
}

func makePluginClient(p getter.CompatPlugin) (logPlugin, error) {
	if pc, ok := p.(getter.PluginWithV1Client); ok {
		return &logPluginProxy{pc.Client()}, nil
	}
	pa, ok := p.(getter.PluginAddr)
	if !ok {
		return nil, errdefs.System(errors.Errorf("got unknown plugin type %T", p))
	}

	if pa.Protocol() != plugins.ProtocolSchemeHTTPV1 {
		return nil, errors.Errorf("plugin protocol not supported: %s", p)
	}

	addr := pa.Addr()
	c, err := plugins.NewClientWithTimeout(addr.Network()+"://"+addr.String(), nil, pa.Timeout())
	if err != nil {
		return nil, errors.Wrap(err, "error making plugin client")
	}
	return &logPluginProxy{c}, nil
}

func makePluginCreator(name string, l logPlugin, scopePath func(s string) string) Creator {
	return func(logCtx Info) (logger Logger, err error) {
		defer func() {
			if err != nil {
				pluginGetter.Get(name, extName, getter.Release)
			}
		}()

		unscopedPath := filepath.Join("/", "run", "docker", "logging")
		logRoot := scopePath(unscopedPath)
		if err := os.MkdirAll(logRoot, 0700); err != nil {
			return nil, err
		}

		id := stringid.GenerateRandomID()
		a := &pluginAdapter{
			driverName: name,
			id:         id,
			plugin:     l,
			fifoPath:   filepath.Join(logRoot, id),
			logInfo:    logCtx,
		}

		cap, err := a.plugin.Capabilities()
		if err == nil {
			a.capabilities = cap
		}

		stream, err := openPluginStream(a)
		if err != nil {
			return nil, err
		}

		a.stream = stream
		a.enc = logdriver.NewLogEntryEncoder(a.stream)

		if err := l.StartLogging(filepath.Join(unscopedPath, id), logCtx); err != nil {
			return nil, errors.Wrapf(err, "error creating logger")
		}

		if cap.ReadLogs {
			return &pluginAdapterWithRead{a}, nil
		}

		return a, nil
	}
}
