// Copyright 2020 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.

package osmisc

import (
	"bytes"
	"io/ioutil"
	"os"
	"path/filepath"
	"testing"
)

func TestDirIsEmpty(t *testing.T) {
	tmpdir, err := ioutil.TempDir("", "")
	if err != nil {
		t.Fatalf("failed to create temp dir: %v", err)
	}
	defer os.RemoveAll(tmpdir)

	// Directory should start off empty.
	empty, err := DirIsEmpty(tmpdir)
	if err != nil {
		t.Fatal(err.Error())
	} else if !empty {
		t.Fatalf("directory should be empty")
	}

	if err := ioutil.WriteFile(filepath.Join(tmpdir, "file.txt"), []byte("content"), os.ModePerm); err != nil {
		t.Fatal(err.Error())
	}

	// Directory should now be non-empty.
	empty, err = DirIsEmpty(tmpdir)
	if err != nil {
		t.Fatal(err.Error())
	} else if empty {
		t.Fatalf("directory should be non-empty")
	}

	// Non-existent directories should be empty by convention.
	nonexistentSubdir := filepath.Join(tmpdir, "i_dont_exist")
	empty, err = DirIsEmpty(nonexistentSubdir)
	if err != nil {
		t.Fatal(err.Error())
	} else if !empty {
		t.Fatalf("non-existent directory should be empty")
	}

}

func TestCopyDir(t *testing.T) {
	tmpDir, err := ioutil.TempDir("", "osmisc")
	if err != nil {
		t.Fatalf("failed to create a temporary directory: %v", err)
	}
	defer os.RemoveAll(tmpDir)

	srcDir := filepath.Join(tmpDir, "src")
	if err := os.Mkdir(srcDir, 0700); err != nil {
		t.Fatalf("failed to create src %q: %v", srcDir, err)
	}

	dstDir := filepath.Join(tmpDir, "dst")
	if err := os.Mkdir(dstDir, os.ModePerm); err != nil {
		t.Fatalf("failed to create dst %q: %v", dstDir, err)
	}

	srcPaths := map[string]string{
		"a":     "a",
		"b":     "",
		"b/a":   "b/a",
		"b/b":   "b/b",
		"b/c":   "",
		"b/c/a": "b/c/a",
	}

	for path, contents := range srcPaths {
		path = filepath.Join(srcDir, path)

		if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil {
			t.Fatalf("failed to create path %q: %v", path, err)
		}

		if contents == "" {
			if err := os.MkdirAll(path, 0700); err != nil {
				t.Fatalf("failed to create path %q: %v", path, err)
			}
		} else {
			if err := ioutil.WriteFile(path, []byte(contents), 0400); err != nil {
				t.Fatalf("failed to write contents to src %q: %v", path, err)
			}
		}
	}

	if err := os.Symlink(filepath.Join(srcDir, "a"), filepath.Join(srcDir, "c")); err != nil {
		t.Fatalf("failed to create symlink: %v", err)
	}
	srcPaths["c"] = "a"

	if err := CopyDir(srcDir, dstDir); err != nil {
		t.Fatalf("failed to copy directory: %v", err)
	}

	err = filepath.Walk(dstDir, func(dstPath string, dstInfo os.FileInfo, err error) error {
		if dstDir == dstPath {
			return nil
		}

		if err != nil {
			return err
		}

		relPath, err := filepath.Rel(dstDir, dstPath)
		if err != nil {
			t.Fatalf("failed to get relative path for dst: %v", err)
		}

		if _, ok := srcPaths[relPath]; !ok {
			t.Fatalf("unknown path %q", relPath)
		}
		delete(srcPaths, relPath)

		srcPath := filepath.Join(srcDir, relPath)
		srcInfo, err := os.Lstat(srcPath)
		if err != nil {
			t.Fatalf("failed to stat src %q: %v", srcPath, err)
		}

		if srcInfo.Mode() != dstInfo.Mode() {
			t.Fatalf("mode not copied from %q to %q: %s != %s", srcPath, dstPath, srcInfo.Mode(), dstInfo.Mode())
		}

		if !srcInfo.IsDir() {
			srcContents, err := ioutil.ReadFile(srcPath)
			if err != nil {
				t.Fatalf("failed to read src %q: %v", srcPath, err)
			}

			dstContents, err := ioutil.ReadFile(dstPath)
			if err != nil {
				t.Fatalf("failed to read dst %q: %v", dstPath, err)
			}

			if !bytes.Equal(srcContents, dstContents) {
				t.Fatalf("src %q has different contents than dst %q", srcPath, dstPath)
			}
		}

		return nil
	})
	if err != nil {
		t.Fatalf("failed to walk directory: %v", err)
	}

	if len(srcPaths) != 0 {
		t.Fatalf("some files not copied: %+v", srcPaths)
	}
}
