// Copyright 2017 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package logger

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"reflect"
	"sort"
	"syscall"
	"testing"
)

func TestCreateFileWithRotation(t *testing.T) {
	dir, err := ioutil.TempDir("", "test-rotation")
	if err != nil {
		t.Fatalf("Failed to get TempDir: %v", err)
	}
	defer os.RemoveAll(dir)

	file := filepath.Join(dir, "build.log")

	writeFile := func(name string, data string) {
		f, err := CreateFileWithRotation(name, 3)
		if err != nil {
			t.Fatalf("Failed to create file: %v", err)
		}
		if n, err := io.WriteString(f, data); err == nil && n < len(data) {
			t.Fatalf("Short write")
		} else if err != nil {
			t.Fatalf("Failed to write: %v", err)
		}
		if err := f.Close(); err != nil {
			t.Fatalf("Failed to close: %v", err)
		}
	}

	writeFile(file, "a")
	writeFile(file, "b")
	writeFile(file, "c")
	writeFile(file, "d")
	writeFile(file, "e")

	d, err := os.Open(dir)
	if err != nil {
		t.Fatalf("Failed to open dir: %v", err)
	}
	names, err := d.Readdirnames(0)
	if err != nil {
		t.Fatalf("Failed to read dir: %v", err)
	}
	sort.Strings(names)
	expected := []string{".lock_build.log", "build.1.log", "build.2.log", "build.3.log", "build.log"}
	if !reflect.DeepEqual(names, expected) {
		t.Errorf("File list does not match.")
		t.Errorf("     got: %v", names)
		t.Errorf("expected: %v", expected)
		t.FailNow()
	}

	expectFileContents := func(name, expected string) {
		data, err := ioutil.ReadFile(filepath.Join(dir, name))
		if err != nil {
			t.Errorf("Error reading file: %v", err)
			return
		}
		str := string(data)
		if str != expected {
			t.Errorf("Contents of %v does not match.", name)
			t.Errorf("     got: %v", data)
			t.Errorf("expected: %v", expected)
		}
	}

	expectFileContents("build.log", "e")
	expectFileContents("build.1.log", "d")
	expectFileContents("build.2.log", "c")
	expectFileContents("build.3.log", "b")
}

func TestPanic(t *testing.T) {
	if os.Getenv("ACTUALLY_PANIC") == "1" {
		panicValue := "foo"
		log := New(&bytes.Buffer{})

		defer func() {
			p := recover()

			if p == panicValue {
				os.Exit(42)
			} else {
				fmt.Fprintf(os.Stderr, "Expected %q, got %v\n", panicValue, p)
				os.Exit(3)
			}
		}()
		defer log.Cleanup()

		log.Panic(panicValue)
		os.Exit(2)
		return
	}

	// Run this in an external process so that we don't pollute stderr
	cmd := exec.Command(os.Args[0], "-test.run=TestPanic")
	cmd.Env = append(os.Environ(), "ACTUALLY_PANIC=1")
	err := cmd.Run()
	if e, ok := err.(*exec.ExitError); ok && e.Sys().(syscall.WaitStatus).ExitStatus() == 42 {
		return
	}
	t.Errorf("Expected process to exit with status 42, got %v", err)
}

func TestFatal(t *testing.T) {
	if os.Getenv("ACTUALLY_FATAL") == "1" {
		log := New(&bytes.Buffer{})
		defer func() {
			// Shouldn't get here
			os.Exit(3)
		}()
		defer log.Cleanup()
		log.Fatal("Test")
		os.Exit(0)
		return
	}

	cmd := exec.Command(os.Args[0], "-test.run=TestFatal")
	cmd.Env = append(os.Environ(), "ACTUALLY_FATAL=1")
	err := cmd.Run()
	if e, ok := err.(*exec.ExitError); ok && e.Sys().(syscall.WaitStatus).ExitStatus() == 1 {
		return
	}
	t.Errorf("Expected process to exit with status 1, got %v", err)
}

func TestNonFatal(t *testing.T) {
	if os.Getenv("ACTUAL_TEST") == "1" {
		log := New(&bytes.Buffer{})
		defer log.Cleanup()
		log.Println("Test")
		return
	}

	cmd := exec.Command(os.Args[0], "-test.run=TestNonFatal")
	cmd.Env = append(os.Environ(), "ACTUAL_TEST=1")
	err := cmd.Run()
	if e, ok := err.(*exec.ExitError); ok || (ok && !e.Success()) {
		t.Errorf("Expected process to exit cleanly, got %v", err)
	}
}

func TestRecoverFatal(t *testing.T) {
	log := New(&bytes.Buffer{})
	defer func() {
		if p := recover(); p != nil {
			t.Errorf("Unexpected panic: %#v", p)
		}
	}()
	defer Recover(func(err error) {
		if err.Error() != "Test" {
			t.Errorf("Expected %q, but got %q", "Test", err.Error())
		}
	})
	log.Fatal("Test")
	t.Errorf("Should not get here")
}

func TestRecoverNonFatal(t *testing.T) {
	log := New(&bytes.Buffer{})
	defer func() {
		if p := recover(); p == nil {
			t.Errorf("Panic not thrown")
		} else if p != "Test" {
			t.Errorf("Expected %q, but got %#v", "Test", p)
		}
	}()
	defer Recover(func(err error) {
		t.Errorf("Recover function should not be called")
	})
	log.Panic("Test")
	t.Errorf("Should not get here")
}

func TestRuntimePanic(t *testing.T) {
	defer func() {
		if p := recover(); p == nil {
			t.Errorf("Panic not thrown")
		}
	}()
	defer Recover(func(err error) {
		t.Errorf("Recover function should not be called")
	})
	var i *int
	*i = 0
	t.Errorf("Should not get here")
}
