// Copyright 2017 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 far

import (
	"bytes"
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"sort"
	"strings"
	"testing"
)

func TestWrite(t *testing.T) {
	files := []string{"a", "b", "dir/c"}
	d := create(t, files)
	defer os.Remove(d)

	inputs := map[string]string{}
	for _, path := range files {
		inputs[path] = filepath.Join(d, path)
	}

	w := bytes.NewBuffer(nil)
	if err := Write(w, inputs); err != nil {
		t.Fatal(err)
	}

	far := w.Bytes()

	if !bytes.Equal(far[0:8], []byte(Magic)) {
		t.Errorf("got %x, want %x", far[0:8], []byte(Magic))
	}

	if !bytes.Equal(far, exampleArchive()) {
		t.Errorf("archives didn't match, got:\n%s", hex.Dump(far))
	}
}

func TestLengths(t *testing.T) {
	if want := 16; IndexLen != want {
		t.Errorf("IndexLen: got %d, want %d", IndexLen, want)
	}
	if want := 24; IndexEntryLen != want {
		t.Errorf("IndexEntryLen: got %d, want %d", IndexEntryLen, want)
	}
	if want := 32; DirectoryEntryLen != want {
		t.Errorf("DirectoryEntryLen: got %d, want %d", DirectoryEntryLen, want)
	}
}

// create makes a temporary directory and populates it with the files in
// the given slice. the files will contain their name as content. The path of
// the created directory is returned.
func create(t *testing.T, files []string) string {
	d, err := ioutil.TempDir("", t.Name())
	if err != nil {
		t.Fatal(err)
	}
	for _, path := range files {
		absPath := filepath.Join(d, path)
		if err := os.MkdirAll(filepath.Dir(absPath), os.ModePerm); err != nil {
			t.Fatal(err)
		}
		f, err := os.Create(absPath)
		if err != nil {
			t.Fatal(err)
		}
		if _, err := fmt.Fprintf(f, "%s\n", path); err != nil {
			t.Fatal(err)
		}
		if err := f.Close(); err != nil {
			t.Fatal(err)
		}
	}
	return d
}

func TestReader(t *testing.T) {
	_, err := NewReader(bytes.NewReader(exampleArchive()))
	if err != nil {
		t.Fatal(err)
	}

	corruptors := []func([]byte){
		// corrupt magic
		func(b []byte) { b[0] = 0 },
		// corrupt index length
		func(b []byte) { binary.LittleEndian.PutUint64(b[8:], 1) },
		// corrupt dirindex type
		func(b []byte) { b[IndexLen] = 255 },
		// TODO(raggi): corrupt index entry offset
		// TODO(raggi): remove index entries
	}

	for i, corrupt := range corruptors {
		far := exampleArchive()
		corrupt(far)
		_, err := NewReader(bytes.NewReader(far))
		if _, ok := err.(ErrInvalidArchive); !ok {
			t.Errorf("corrupt archive %d, got unexpected error %v", i, err)
		}
	}
}

func TestListFiles(t *testing.T) {
	far := exampleArchive()
	r, err := NewReader(bytes.NewReader(far))
	if err != nil {
		t.Fatal(err)
	}

	files := r.List()

	want := []string{"a", "b", "dir/c"}

	if len(files) != len(want) {
		t.Fatalf("listfiles: got %v, want %v", files, want)
	}

	sort.Strings(files)

	for i, want := range want {
		if got := files[i]; got != want {
			t.Errorf("listfiles: got %q, want %q at %d", got, want, i)
		}
	}
}

func TestReaderOpen(t *testing.T) {
	far := exampleArchive()
	r, err := NewReader(bytes.NewReader(far))
	if err != nil {
		t.Fatal(err)
	}

	if got, want := len(r.dirEntries), 3; got != want {
		t.Errorf("got %v, want %v", got, want)
	}

	for _, f := range []string{"a", "b", "dir/c"} {
		ra, err := r.Open(f)
		if err != nil {
			t.Fatal(err)
		}
		// buffer past the far content padding to check clamping of the readat range
		want := make([]byte, 10*1024)
		copy(want, []byte(f))
		want[len(f)] = '\n'
		got := make([]byte, 10*1024)

		n, err := ra.ReadAt(got, 0)
		if err != nil {
			t.Fatal(err)
		}
		if want := len(f) + 1; n != want {
			t.Errorf("got %d, want %d", n, want)
		}
		if !bytes.Equal(got, want) {
			t.Errorf("got %x, want %x", got, want)
		}
	}

	ra, err := r.Open("a")
	if err != nil {
		t.Fatal(err)
	}
	// ensure that negative offsets are rejected
	n, err := ra.ReadAt(make([]byte, 10), -10)
	if err != io.EOF || n != 0 {
		t.Errorf("got %d %v, want %d, %v", n, err, 0, io.EOF)
	}
	// ensure that offsets beyond length are rejected
	n, err = ra.ReadAt(make([]byte, 10), 10)
	if err != io.EOF || n != 0 {
		t.Errorf("got %d %v, want %d, %v", n, err, 0, io.EOF)
	}
}
func TestReaderReadFile(t *testing.T) {
	far := exampleArchive()
	r, err := NewReader(bytes.NewReader(far))
	if err != nil {
		t.Fatal(err)
	}

	if got, want := len(r.dirEntries), 3; got != want {
		t.Errorf("got %v, want %v", got, want)
	}

	for _, f := range []string{"a", "b", "dir/c"} {
		got, err := r.ReadFile(f)
		if err != nil {
			t.Fatal(err)
		}
		// buffer past the far content padding to check clamping of the readat range
		want := []byte(f + "\n")
		if !bytes.Equal(got, want) {
			t.Errorf("got %x, want %x", got, want)
		}
	}

	ra, err := r.Open("a")
	if err != nil {
		t.Fatal(err)
	}
	// ensure that negative offsets are rejected
	n, err := ra.ReadAt(make([]byte, 10), -10)
	if err != io.EOF || n != 0 {
		t.Errorf("got %d %v, want %d, %v", n, err, 0, io.EOF)
	}
	// ensure that offsets beyond length are rejected
	n, err = ra.ReadAt(make([]byte, 10), 10)
	if err != io.EOF || n != 0 {
		t.Errorf("got %d %v, want %d, %v", n, err, 0, io.EOF)
	}
}

func TestReaderGetSize(t *testing.T) {
	far := exampleArchive()

	r, err := NewReader(bytes.NewReader(far))
	if err != nil {
		t.Fatal(err)
	}

	if got, want := r.GetSize("a"), uint64(2); got != want {
		t.Errorf("GetSize() = %d, want %d", got, want)
	}
}

func TestReadEmpty(t *testing.T) {
	r, err := NewReader(bytes.NewReader(emptyArchive()))
	if err != nil {
		t.Fatal(err)
	}
	if len(r.List()) != 0 {
		t.Error("empty archive should contain no files")
	}
}

func TestIsFAR(t *testing.T) {
	type args struct {
		r io.Reader
	}
	tests := []struct {
		name string
		args args
		want bool
	}{
		{
			name: "valid magic",
			args: args{strings.NewReader(Magic)},
			want: true,
		},
		{
			name: "empty",
			args: args{strings.NewReader("")},
			want: false,
		},
		{
			name: "not magic",
			args: args{strings.NewReader("ohai")},
			want: false,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := IsFAR(tt.args.r); got != tt.want {
				t.Errorf("IsFAR() = %v, want %v", got, tt.want)
			}
		})
	}
}

// exampleArchive produces an archive similar to far(1) output
func exampleArchive() []byte {
	b := make([]byte, 16384)
	copy(b, []byte{
		0xc8, 0xbf, 0x0b, 0x48, 0xad, 0xab, 0xc5, 0x11, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x44, 0x49, 0x52, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0x52, 0x4e, 0x41, 0x4d, 0x45, 0x53,
		0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x61, 0x62, 0x64, 0x69, 0x72, 0x2f, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	})
	copy(b[4096:], []byte("a\n"))
	copy(b[8192:], []byte("b\n"))
	copy(b[12288:], []byte("dir/c\n"))
	return b
}

func emptyArchive() []byte {
	return []byte{0xc8, 0xbf, 0xb, 0x48, 0xad, 0xab, 0xc5, 0x11, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
}
