// Package etwlogs provides a log driver for forwarding container logs
// as ETW events.(ETW stands for Event Tracing for Windows)
// A client can then create an ETW listener to listen for events that are sent
// by the ETW provider that we register, using the provider's GUID "a3693192-9ed6-46d2-a981-f8226c8363bd".
// Here is an example of how to do this using the logman utility:
// 1. logman start -ets DockerContainerLogs -p {a3693192-9ed6-46d2-a981-f8226c8363bd} 0 0 -o trace.etl
// 2. Run container(s) and generate log messages
// 3. logman stop -ets DockerContainerLogs
// 4. You can then convert the etl log file to XML using: tracerpt -y trace.etl
//
// Each container log message generates an ETW event that also contains:
// the container name and ID, the timestamp, and the stream type.
package etwlogs

import (
	"errors"
	"fmt"
	"sync"
	"syscall"
	"unsafe"

	"github.com/Sirupsen/logrus"
	"github.com/docker/docker/daemon/logger"
)

type etwLogs struct {
	containerName string
	imageName     string
	containerID   string
	imageID       string
}

const (
	name             = "etwlogs"
	win32CallSuccess = 0
)

var win32Lib *syscall.DLL
var providerHandle syscall.Handle
var refCount int
var mu sync.Mutex

func init() {
	providerHandle = syscall.InvalidHandle
	if err := logger.RegisterLogDriver(name, New); err != nil {
		logrus.Fatal(err)
	}
}

// New creates a new etwLogs logger for the given container and registers the EWT provider.
func New(ctx logger.Context) (logger.Logger, error) {
	if err := registerETWProvider(); err != nil {
		return nil, err
	}
	logrus.Debugf("logging driver etwLogs configured for container: %s.", ctx.ContainerID)

	return &etwLogs{
		containerName: fixContainerName(ctx.ContainerName),
		imageName:     ctx.ContainerImageName,
		containerID:   ctx.ContainerID,
		imageID:       ctx.ContainerImageID,
	}, nil
}

// Log logs the message to the ETW stream.
func (etwLogger *etwLogs) Log(msg *logger.Message) error {
	if providerHandle == syscall.InvalidHandle {
		// This should never be hit, if it is, it indicates a programming error.
		errorMessage := "ETWLogs cannot log the message, because the event provider has not been registered."
		logrus.Error(errorMessage)
		return errors.New(errorMessage)
	}
	return callEventWriteString(createLogMessage(etwLogger, msg))
}

// Close closes the logger by unregistering the ETW provider.
func (etwLogger *etwLogs) Close() error {
	unregisterETWProvider()
	return nil
}

func (etwLogger *etwLogs) Name() string {
	return name
}

func createLogMessage(etwLogger *etwLogs, msg *logger.Message) string {
	return fmt.Sprintf("container_name: %s, image_name: %s, container_id: %s, image_id: %s, source: %s, log: %s",
		etwLogger.containerName,
		etwLogger.imageName,
		etwLogger.containerID,
		etwLogger.imageID,
		msg.Source,
		msg.Line)
}

// fixContainerName removes the initial '/' from the container name.
func fixContainerName(cntName string) string {
	if len(cntName) > 0 && cntName[0] == '/' {
		cntName = cntName[1:]
	}
	return cntName
}

func registerETWProvider() error {
	mu.Lock()
	defer mu.Unlock()
	if refCount == 0 {
		var err error
		if win32Lib, err = syscall.LoadDLL("Advapi32.dll"); err != nil {
			return err
		}
		if err = callEventRegister(); err != nil {
			win32Lib.Release()
			win32Lib = nil
			return err
		}
	}

	refCount++
	return nil
}

func unregisterETWProvider() {
	mu.Lock()
	defer mu.Unlock()
	if refCount == 1 {
		if callEventUnregister() {
			refCount--
			providerHandle = syscall.InvalidHandle
			win32Lib.Release()
			win32Lib = nil
		}
		// Not returning an error if EventUnregister fails, because etwLogs will continue to work
	} else {
		refCount--
	}
}

func callEventRegister() error {
	proc, err := win32Lib.FindProc("EventRegister")
	if err != nil {
		return err
	}
	// The provider's GUID is {a3693192-9ed6-46d2-a981-f8226c8363bd}
	guid := syscall.GUID{
		0xa3693192, 0x9ed6, 0x46d2,
		[8]byte{0xa9, 0x81, 0xf8, 0x22, 0x6c, 0x83, 0x63, 0xbd},
	}

	ret, _, _ := proc.Call(uintptr(unsafe.Pointer(&guid)), 0, 0, uintptr(unsafe.Pointer(&providerHandle)))
	if ret != win32CallSuccess {
		errorMessage := fmt.Sprintf("Failed to register ETW provider. Error: %d", ret)
		logrus.Error(errorMessage)
		return errors.New(errorMessage)
	}
	return nil
}

func callEventWriteString(message string) error {
	proc, err := win32Lib.FindProc("EventWriteString")
	if err != nil {
		return err
	}
	ret, _, _ := proc.Call(uintptr(providerHandle), 0, 0, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(message))))
	if ret != win32CallSuccess {
		errorMessage := fmt.Sprintf("ETWLogs provider failed to log message. Error: %d", ret)
		logrus.Error(errorMessage)
		return errors.New(errorMessage)
	}
	return nil
}

func callEventUnregister() bool {
	proc, err := win32Lib.FindProc("EventUnregister")
	if err != nil {
		return false
	}
	ret, _, _ := proc.Call(uintptr(providerHandle))
	if ret != win32CallSuccess {
		return false
	}
	return true
}
