// Copyright 2016 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 fsnotify

import (
	"os"
	"path/filepath"
	"testing"
	"time"

	"golang.org/x/sys/unix"
)

// testExchangedataForWatcher tests the watcher with the exchangedata operation on macOS.
//
// This is widely used for atomic saves on macOS, e.g. TextMate and in Apple's NSDocument.
//
// See https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man2/exchangedata.2.html
// Also see: https://github.com/textmate/textmate/blob/cd016be29489eba5f3c09b7b70b06da134dda550/Frameworks/io/src/swap_file_data.cc#L20
func testExchangedataForWatcher(t *testing.T, watchDir bool) {
	// Create directory to watch
	testDir1 := tempMkdir(t)

	// For the intermediate file
	testDir2 := tempMkdir(t)

	defer os.RemoveAll(testDir1)
	defer os.RemoveAll(testDir2)

	resolvedFilename := "TestFsnotifyEvents.file"

	// TextMate does:
	//
	// 1. exchangedata (intermediate, resolved)
	// 2. unlink intermediate
	//
	// Let's try to simulate that:
	resolved := filepath.Join(testDir1, resolvedFilename)
	intermediate := filepath.Join(testDir2, resolvedFilename+"~")

	// Make sure we create the file before we start watching
	createAndSyncFile(t, resolved)

	watcher := newWatcher(t)

	// Test both variants in isolation
	if watchDir {
		addWatch(t, watcher, testDir1)
	} else {
		addWatch(t, watcher, resolved)
	}

	// Receive errors on the error channel on a separate goroutine
	go func() {
		for err := range watcher.Errors {
			t.Fatalf("error received: %s", err)
		}
	}()

	// Receive events on the event channel on a separate goroutine
	eventstream := watcher.Events
	var removeReceived counter
	var createReceived counter

	done := make(chan bool)

	go func() {
		for event := range eventstream {
			// Only count relevant events
			if event.Name == filepath.Clean(resolved) {
				if event.Op&Remove == Remove {
					removeReceived.increment()
				}
				if event.Op&Create == Create {
					createReceived.increment()
				}
			}
			t.Logf("event received: %s", event)
		}
		done <- true
	}()

	// Repeat to make sure the watched file/directory "survives" the REMOVE/CREATE loop.
	for i := 1; i <= 3; i++ {
		// The intermediate file is created in a folder outside the watcher
		createAndSyncFile(t, intermediate)

		// 1. Swap
		if err := unix.Exchangedata(intermediate, resolved, 0); err != nil {
			t.Fatalf("[%d] exchangedata failed: %s", i, err)
		}

		time.Sleep(50 * time.Millisecond)

		// 2. Delete the intermediate file
		err := os.Remove(intermediate)

		if err != nil {
			t.Fatalf("[%d] remove %s failed: %s", i, intermediate, err)
		}

		time.Sleep(50 * time.Millisecond)

	}

	// We expect this event to be received almost immediately, but let's wait 500 ms to be sure
	time.Sleep(500 * time.Millisecond)

	// The events will be (CHMOD + REMOVE + CREATE) X 2. Let's focus on the last two:
	if removeReceived.value() < 3 {
		t.Fatal("fsnotify remove events have not been received after 500 ms")
	}

	if createReceived.value() < 3 {
		t.Fatal("fsnotify create events have not been received after 500 ms")
	}

	watcher.Close()
	t.Log("waiting for the event channel to become closed...")
	select {
	case <-done:
		t.Log("event channel closed")
	case <-time.After(2 * time.Second):
		t.Fatal("event stream was not closed after 2 seconds")
	}
}

// TestExchangedataInWatchedDir test exchangedata operation on file in watched dir.
func TestExchangedataInWatchedDir(t *testing.T) {
	testExchangedataForWatcher(t, true)
}

// TestExchangedataInWatchedDir test exchangedata operation on watched file.
func TestExchangedataInWatchedFile(t *testing.T) {
	testExchangedataForWatcher(t, false)
}

func createAndSyncFile(t *testing.T, filepath string) {
	f1, err := os.OpenFile(filepath, os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		t.Fatalf("creating %s failed: %s", filepath, err)
	}
	f1.Sync()
	f1.Close()
}
