// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//go:build !build_with_native_toolchain
// +build !build_with_native_toolchain

package syslog_test

import (
	"bytes"
	"context"
	"encoding/binary"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"syscall/zx"
	"syscall/zx/fidl"
	"syscall/zx/zxwait"
	"testing"
	"unicode/utf8"

	"fidl/fuchsia/diagnostics"
	"fidl/fuchsia/logger"

	"go.fuchsia.dev/fuchsia/src/lib/component"
	syslog "go.fuchsia.dev/fuchsia/src/lib/syslog/go"
)

const format = "integer: %d"

var pid = uint64(os.Getpid())

var _ logger.LogSinkWithCtx = (*logSinkImpl)(nil)

type logSinkImpl struct {
	onConnect             func(fidl.Context, zx.Socket)
	waitForInterestChange <-chan logger.LogSinkWaitForInterestChangeResult
}

func (impl *logSinkImpl) Connect(ctx fidl.Context, socket zx.Socket) error {
	impl.onConnect(ctx, socket)
	return nil
}

func (*logSinkImpl) ConnectStructured(fidl.Context, zx.Socket) error {
	return nil
}

func (impl *logSinkImpl) WaitForInterestChange(fidl.Context) (logger.LogSinkWaitForInterestChangeResult, error) {
	if result := <-impl.waitForInterestChange; result != (logger.LogSinkWaitForInterestChangeResult{}) {
		return result, nil
	}
	return logger.LogSinkWaitForInterestChangeResult{}, &zx.Error{Status: zx.ErrCanceled}
}

func TestLogSimple(t *testing.T) {
	actual := bytes.Buffer{}
	var options syslog.LogInitOptions
	options.MinSeverityForFileAndLineInfo = syslog.ErrorLevel
	options.Writer = &actual
	log, err := syslog.NewLogger(options)
	if err != nil {
		t.Fatal(err)
	}
	if err := log.Infof(format, 10); err != nil {
		t.Fatal(err)
	}
	expected := "INFO: integer: 10\n"
	got := string(actual.Bytes())
	if !strings.HasSuffix(got, expected) {
		t.Errorf("%q should have ended in %q", got, expected)
	}
	if !strings.Contains(got, fmt.Sprintf("[%d]", pid)) {
		t.Errorf("%q should contains %d", got, pid)
	}
}

func setup(t *testing.T, tags ...string) (chan<- logger.LogSinkWaitForInterestChangeResult, zx.Socket, *syslog.Logger) {
	req, logSink, err := logger.NewLogSinkWithCtxInterfaceRequest()
	if err != nil {
		t.Fatal(err)
	}

	ctx, cancel := context.WithCancel(context.Background())
	ch := make(chan struct{})
	t.Cleanup(func() {
		cancel()
		<-ch
	})

	waitForInterestChange := make(chan logger.LogSinkWaitForInterestChangeResult)
	t.Cleanup(func() { close(waitForInterestChange) })

	sinChan := make(chan zx.Socket, 1)
	defer close(sinChan)
	go func() {
		defer close(ch)

		component.Serve(ctx, &logger.LogSinkWithCtxStub{
			Impl: &logSinkImpl{
				onConnect: func(_ fidl.Context, socket zx.Socket) {
					sinChan <- socket
				},
				waitForInterestChange: waitForInterestChange,
			},
		}, req.Channel, component.ServeOptions{
			OnError: func(err error) {
				var zxError *zx.Error
				if errors.As(err, &zxError) {
					if zxError.Status == zx.ErrCanceled {
						return
					}
				}
				t.Error(err)
			},
		})
	}()

	options := syslog.LogInitOptions{
		LogLevel: syslog.InfoLevel,
	}
	options.LogSink = logSink
	options.MinSeverityForFileAndLineInfo = syslog.ErrorLevel
	options.Tags = tags
	log, err := syslog.NewLogger(options)
	if err != nil {
		t.Fatal(err)
	}

	s := <-sinChan

	// Throw away system-generated messages.
	for i := 0; i < 1; i++ {
		if _, err := zxwait.WaitContext(context.Background(), zx.Handle(s), zx.SignalSocketReadable); err != nil {
			t.Fatal(err)
		}
		var data [logger.MaxDatagramLenBytes]byte
		if _, err := s.Read(data[:], 0); err != nil {
			t.Fatal(err)
		}
	}

	return waitForInterestChange, s, log
}

func checkoutput(t *testing.T, sin zx.Socket, expectedMsg string, severity syslog.LogLevel, tags ...string) {
	var data [logger.MaxDatagramLenBytes]byte
	n, err := sin.Read(data[:], 0)
	if err != nil {
		t.Fatal(err)
	}
	if n <= 32 {
		t.Fatalf("got invalid data: %x", data[:n])
	}
	gotpid := binary.LittleEndian.Uint64(data[0:8])
	gotTid := binary.LittleEndian.Uint64(data[8:16])
	gotTime := binary.LittleEndian.Uint64(data[16:24])
	gotSeverity := int32(binary.LittleEndian.Uint32(data[24:28]))
	gotDroppedLogs := int32(binary.LittleEndian.Uint32(data[28:32]))

	if pid != gotpid {
		t.Errorf("pid error, got: %d, want: %d", gotpid, pid)
	}

	if 0 != gotTid {
		t.Errorf("tid error, got: %d, want: %d", gotTid, 0)
	}

	if int32(severity) != gotSeverity {
		t.Errorf("severity error, got: %d, want: %d", gotSeverity, severity)
	}

	if gotTime <= 0 {
		t.Errorf("time %d should be greater than zero", gotTime)
	}

	if 0 != gotDroppedLogs {
		t.Errorf("dropped logs error, got: %d, want: %d", gotDroppedLogs, 0)
	}
	pos := 32
	for i, tag := range tags {
		length := len(tag)
		if data[pos] != byte(length) {
			t.Fatalf("tag iteration %d: expected data to be %d at pos %d, got %d", i, length, pos, data[pos])
		}
		pos = pos + 1
		gotTag := string(data[pos : pos+length])
		if tag != gotTag {
			t.Fatalf("tag iteration %d: expected tag %q , got %q", i, tag, gotTag)
		}
		pos = pos + length
	}

	if data[pos] != 0 {
		t.Fatalf("byte before msg start should be zero, got: %d, %x", data[pos], data[pos:n])
	}

	msgGot := string(data[pos+1 : n-1])
	if expectedMsg != msgGot {
		t.Fatalf("expected msg:%q, got %q", expectedMsg, msgGot)
	}
	if data[n-1] != 0 {
		t.Fatalf("last byte should be zero, got: %d, %x", data[pos], data[32:n])
	}
}

func TestLog(t *testing.T) {
	_, sin, log := setup(t)
	defer func() {
		if err := log.Close(); err != nil {
			t.Error(err)
		}
		if err := sin.Close(); err != nil {
			t.Error(err)
		}
	}()

	if err := log.Infof(format, 10); err != nil {
		t.Fatal(err)
	}
	checkoutput(t, sin, fmt.Sprintf(format, 10), syslog.InfoLevel)
}

func TestLogWithLocalTag(t *testing.T) {
	_, sin, log := setup(t)
	defer func() {
		if err := log.Close(); err != nil {
			t.Error(err)
		}
		if err := sin.Close(); err != nil {
			t.Error(err)
		}
	}()
	if err := log.InfoTf("local_tag", format, 10); err != nil {
		t.Fatal(err)
	}
	expectedMsg := fmt.Sprintf(format, 10)
	checkoutput(t, sin, expectedMsg, syslog.InfoLevel, "local_tag")
}

func TestLogWithGlobalTags(t *testing.T) {
	_, sin, log := setup(t, "gtag1", "gtag2")
	defer func() {
		if err := log.Close(); err != nil {
			t.Error(err)
		}
		if err := sin.Close(); err != nil {
			t.Error(err)
		}
	}()
	if err := log.InfoTf("local_tag", format, 10); err != nil {
		t.Fatal(err)
	}
	expectedMsg := fmt.Sprintf(format, 10)
	checkoutput(t, sin, expectedMsg, syslog.InfoLevel, "gtag1", "gtag2", "local_tag")
}

func TestLoggerSeverity(t *testing.T) {
	_, sin, log := setup(t)
	defer func() {
		if err := log.Close(); err != nil {
			t.Error(err)
		}
		if err := sin.Close(); err != nil {
			t.Error(err)
		}
	}()
	log.SetSeverity(diagnostics.Severity(syslog.WarningLevel))
	if err := log.Infof(format, 10); err != nil {
		t.Fatal(err)
	}
	_, err := sin.Read(nil, 0)
	if err, ok := err.(*zx.Error); !ok || err.Status != zx.ErrShouldWait {
		t.Fatal(err)
	}
	if err := log.Warnf(format, 10); err != nil {
		t.Fatal(err)
	}
	expectedMsg := fmt.Sprintf(format, 10)
	checkoutput(t, sin, expectedMsg, syslog.WarningLevel)
}

func TestLoggerVerbosity(t *testing.T) {
	_, sin, log := setup(t)
	defer func() {
		if err := log.Close(); err != nil {
			t.Error(err)
		}
		if err := sin.Close(); err != nil {
			t.Error(err)
		}
	}()
	if err := log.VLogf(syslog.DebugVerbosity, format, 10); err != nil {
		t.Fatal(err)
	}
	_, err := sin.Read(nil, 0)
	if err, ok := err.(*zx.Error); !ok || err.Status != zx.ErrShouldWait {
		t.Fatal(err)
	}
	log.SetVerbosity(syslog.DebugVerbosity)
	if err := log.VLogf(syslog.DebugVerbosity, format, 10); err != nil {
		t.Fatal(err)
	}
	expectedMsg := fmt.Sprintf(format, 10)
	checkoutput(t, sin, expectedMsg, syslog.InfoLevel-1)
}

func TestLoggerRegisterInterest(t *testing.T) {
	ch, sin, log := setup(t)
	defer func() {
		if err := log.Close(); err != nil {
			t.Error(err)
		}
		if err := sin.Close(); err != nil {
			t.Error(err)
		}
	}()

	registerInterest := func(interest diagnostics.Interest) {
		t.Helper()

		ch <- logger.LogSinkWaitForInterestChangeResultWithResponse(logger.LogSinkWaitForInterestChangeResponse{
			Data: interest,
		})

		// Consume the system-generated messages.
		for i := 0; i < 2; i++ {
			if _, err := zxwait.WaitContext(context.Background(), zx.Handle(sin), zx.SignalSocketReadable); err != nil {
				t.Fatal(err)
			}
			var data [logger.MaxDatagramLenBytes]byte
			if _, err := sin.Read(data[:], 0); err != nil {
				t.Fatal(err)
			}
		}
	}

	// Register interest and observe that the log is emitted.
	{
		var interest diagnostics.Interest
		interest.SetMinSeverity(diagnostics.SeverityDebug)
		registerInterest(interest)
	}
	if err := log.VLogf(syslog.DebugVerbosity, format, 10); err != nil {
		t.Fatal(err)
	}
	expectedMsg := fmt.Sprintf(format, 10)
	checkoutput(t, sin, expectedMsg, syslog.InfoLevel-1)

	// Register empty interest and observe that severity resets to initial.
	registerInterest(diagnostics.Interest{})
	if err := log.VLogf(syslog.DebugVerbosity, format, 10); err != nil {
		t.Fatal(err)
	}
	_, err := sin.Read(nil, 0)
	if err, ok := err.(*zx.Error); !ok || err.Status != zx.ErrShouldWait {
		t.Fatal(err)
	}
}

func TestGlobalTagLimits(t *testing.T) {
	var options syslog.LogInitOptions
	options.Writer = os.Stdout
	var tags [logger.MaxTags + 1]string
	for i := 0; i < len(tags); i++ {
		tags[i] = "a"
	}
	options.Tags = tags[:]
	if _, err := syslog.NewLogger(options); err == nil || !strings.Contains(err.Error(), "too many tags") {
		t.Fatalf("unexpected error: %s", err)
	}
	options.Tags = tags[:logger.MaxTags]
	var tag [logger.MaxTagLenBytes + 1]byte
	for i := 0; i < len(tag); i++ {
		tag[i] = 65
	}
	options.Tags[1] = string(tag[:])
	if _, err := syslog.NewLogger(options); err == nil || !strings.Contains(err.Error(), "tag too long") {
		t.Fatalf("unexpected error: %s", err)
	}
}

func TestLocalTagLimits(t *testing.T) {
	_, sin, log := setup(t)
	defer func() {
		if err := log.Close(); err != nil {
			t.Error(err)
		}
		if err := sin.Close(); err != nil {
			t.Error(err)
		}
	}()
	var tag [logger.MaxTagLenBytes + 1]byte
	for i := 0; i < len(tag); i++ {
		tag[i] = 65
	}
	if err := log.InfoTf(string(tag[:]), format, 10); err != nil {
		t.Fatal(err)
	}
	expectedMsg := fmt.Sprintf(format, 10)
	checkoutput(t, sin, expectedMsg, syslog.InfoLevel, string(tag[:logger.MaxTagLenBytes]))
}

func TestLogToWriterWhenSocketCloses(t *testing.T) {
	_, sin, log := setup(t, "gtag1", "gtag2")
	defer func() {
		if err := log.Close(); err != nil {
			t.Error(err)
		}
	}()
	if err := sin.Close(); err != nil {
		t.Fatal(err)
	}
	old := os.Stderr
	defer func() {
		os.Stderr = old
	}()

	f, err := os.Create(filepath.Join(t.TempDir(), "syslog-test"))
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		if err := f.Close(); err != nil {
			t.Error(err)
		}
	}()
	os.Stderr = f
	if err := log.InfoTf("local_tag", format, 10); err != nil {
		t.Fatal(err)
	}
	if err := f.Sync(); err != nil {
		t.Fatal(err)
	}
	expectedMsg := fmt.Sprintf("[0][gtag1, gtag2, local_tag] INFO: %s\n", fmt.Sprintf(format, 10))
	content, err := ioutil.ReadFile(f.Name())
	os.Stderr = old
	if err != nil {
		t.Fatal(err)
	}
	got := string(content)
	if !strings.HasSuffix(got, expectedMsg) {
		t.Fatalf("%q should have ended in %q", got, expectedMsg)
	}
}

func TestMessageLenLimit(t *testing.T) {
	_, sin, log := setup(t)
	defer func() {
		if err := log.Close(); err != nil {
			t.Error(err)
		}
		if err := sin.Close(); err != nil {
			t.Error(err)
		}
	}()
	// 1 for starting and ending null bytes.
	msgLen := int(logger.MaxDatagramLenBytes) - 32 - 1 - 1

	const stripped = '𠜎'
	// Ensure only part of stripped fits.
	msg := strings.Repeat("x", msgLen-(utf8.RuneLen(stripped)-1)) + string(stripped)
	switch err := log.Infof(msg).(type) {
	case *syslog.ErrMsgTooLong:
		if err.Msg != string(stripped) {
			t.Fatalf("unexpected truncation: %s", err.Msg)
		}
	default:
		t.Fatalf("unexpected error: %#v", err)
	}

	const ellipsis = "..."
	expectedMsg := msg[:msgLen-len(ellipsis)] + ellipsis
	checkoutput(t, sin, expectedMsg, syslog.InfoLevel)
}
