/*
 * Copyright 2018 The Kythe Authors. 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 riegeli

import (
	"bytes"
	"encoding/hex"
	"fmt"
	"io"
	"log"
	"testing"

	"kythe.io/kythe/go/util/compare"

	"github.com/golang/protobuf/proto"

	rtpb "kythe.io/kythe/go/util/riegeli/riegeli_test_go_proto"
	rmpb "kythe.io/third_party/riegeli/records_metadata_go_proto"
)

func TestParseOptions(t *testing.T) {
	tests := []string{
		"",
		"default",
		"brotli",
		"brotli:5",
		"transpose",
		"uncompressed",
		"zstd",
		"zstd:5",
		"brotli,transpose",
		"transpose,uncompressed",
		"brotli:5,transpose",
		"chunk_size:524288",
	}

	for _, test := range tests {
		opts, err := ParseOptions(test)
		if err != nil {
			t.Errorf("ParseOptions error: %v", err)
			continue
		}

		if found := opts.String(); found != test {
			t.Errorf("Expected: %q; found: %q", test, found)
		}
	}
}

func TestWriteEmpty(t *testing.T) {
	var buf bytes.Buffer
	if err := NewWriter(&buf, nil).Close(); err != nil {
		t.Fatal(err)
	}

	// The standard Riegeli file header
	expected := []byte{
		0x83, 0xaf, 0x70, 0xd1, 0x0d, 0x88, 0x4a, 0x3f,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x91, 0xba, 0xc2, 0x3c, 0x92, 0x87, 0xe1, 0xa9,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0xe1, 0x9f, 0x13, 0xc0, 0xe9, 0xb1, 0xc3, 0x72,
		0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	}
	if found := buf.Bytes(); !bytes.Equal(found, expected) {
		t.Errorf("Found: %s; expected: %s", hex.EncodeToString(found), hex.EncodeToString(expected))
	}
}

var testedOptions = []string{
	"default",
	"uncompressed",
	"brotli",
	"zstd",

	"transpose",
	"uncompressed,transpose",
	"brotli,transpose",
}

func TestReadWriteNonProto(t *testing.T) {
	for _, test := range testedOptions {
		opts, err := ParseOptions(test)
		if err != nil {
			t.Fatal(err)
		}
		t.Run(test, func(t *testing.T) {
			t.Parallel()
			testReadWriteStrings(t, opts)
		})
	}
}

func TestReadWriteProto(t *testing.T) {
	for _, test := range testedOptions {
		opts, err := ParseOptions(test)
		if err != nil {
			t.Fatal(err)
		}
		t.Run(test, func(t *testing.T) {
			t.Parallel()
			testReadWriteProtos(t, opts)
		})
	}
}

func writeStrings(t *testing.T, opts *WriterOptions, n int) *bytes.Buffer {
	var buf bytes.Buffer
	wr := NewWriter(&buf, opts)

	for i := 0; i < n; i++ {
		if err := wr.Put([]byte(fmt.Sprintf("%d", i))); err != nil {
			t.Fatalf("Error Put(%d): %v", i, err)
		}
	}
	if err := wr.Close(); err != nil {
		t.Fatalf("Close error: %v", err)
	}
	return &buf
}

func testReadWriteStrings(t *testing.T, opts *WriterOptions) {
	const N = 1e5
	buf := writeStrings(t, opts, N)
	rd := NewReader(bytes.NewReader(buf.Bytes()))
	for i := 0; i < N; i++ {
		rec, err := rd.Next()
		if err != nil {
			t.Fatalf("Read error: %v", err)
		} else if string(rec) != fmt.Sprintf("%d", i) {
			t.Errorf("Found: %s; expected: %d;", hex.EncodeToString(rec), i)
		}
	}
	rec, err := rd.Next()
	if err != io.EOF {
		t.Errorf("Unexpected final Read: %q %v", hex.EncodeToString(rec), err)
	}
}

func writeProtos(t *testing.T, opts *WriterOptions, n int) *bytes.Buffer {
	t.Helper()
	var buf bytes.Buffer
	wr := NewWriter(&buf, opts)
	for i := 0; i < n; i++ {
		if err := wr.PutProto(numToProto(i)); err != nil {
			t.Fatalf("Error PutProto(%d): %v", i, err)
		}
	}
	if err := wr.Close(); err != nil {
		t.Fatalf("Close error: %v", err)
	}
	return &buf
}

// numToProto constructs a *rtpb.Complex using a given integer as its field
// values and as counter for repeated field sizes.
func numToProto(i int) *rtpb.Complex {
	msg := &rtpb.Complex{
		Str:  proto.String(fmt.Sprintf("s%d", i)),
		I32:  proto.Int32(int32(i)),
		I64:  proto.Int64(int64(i)),
		Bits: []byte(fmt.Sprintf("b%d", i)),
		SimpleNested: &rtpb.Simple{
			Name: proto.String(fmt.Sprintf("name%d", i)),
		},
	}
	for j := 0; j < i%8; j++ {
		msg.Rep = append(msg.Rep, fmt.Sprintf("rep%d_%d", i, j))
		msg.Group = append(msg.Group, &rtpb.Complex_Group{
			GrpStr: proto.String(fmt.Sprintf("gs%d_%d", i, j)),
		})
	}
	for j, complexNested := 0, msg; j < i%100; j++ {
		nextLevel := &rtpb.Complex{Str: proto.String(fmt.Sprintf("cn%d_%d", i, j))}
		complexNested.ComplexNested, complexNested = nextLevel, nextLevel
	}
	return msg
}

func testReadWriteProtos(t *testing.T, opts *WriterOptions) {
	const N = 1e3
	buf := writeProtos(t, opts, N)
	log.Printf("Compressed size of %q: %d bytes", t.Name(), buf.Len())
	rd := NewReader(bytes.NewReader(buf.Bytes()))
	for i := 0; i < N; i++ {
		expected := numToProto(i)
		var found rtpb.Complex
		if err := rd.NextProto(&found); err != nil {
			t.Fatalf("Read error: %v", err)
		} else if diff := compare.ProtoDiff(&found, expected); diff != "" {
			t.Errorf("Unexpected record:  (-: found; +: expected)\n%s", diff)
		}
	}
}

func TestEmptyRecord(t *testing.T) {
	var buf bytes.Buffer
	wr := NewWriter(&buf, nil)

	if err := wr.Put([]byte{}); err != nil {
		t.Fatalf("Error writing empty record: %v", err)
	} else if err := wr.Close(); err != nil {
		t.Fatalf("Close error: %v", err)
	}

	rd := NewReader(bytes.NewReader(buf.Bytes()))
	if rec, err := rd.Next(); err != nil {
		t.Fatalf("Error reading empty record: %v", err)
	} else if len(rec) != 0 {
		t.Fatalf("Found non-empty record: %v", rec)
	}

	if rec, err := rd.Next(); err != io.EOF {
		t.Fatalf("Unexpected Next record/error: %v %v", rec, err)
	}
}

func TestReaderSeekRecords(t *testing.T) {
	const N = 1e4
	buf := writeStrings(t, &WriterOptions{}, N)

	rd := NewReadSeeker(bytes.NewReader(buf.Bytes()))
	lastIndex := int64(-1)
	var positions []RecordPosition
	for i := 0; i < N; i++ {
		pos, err := rd.Position()
		if err != nil {
			t.Fatalf("Error getting position: %v", err)
		} else if _, err := rd.Next(); err != nil {
			t.Fatalf("Error reading sequentially: %v", err)
		}
		positions = append(positions, pos)
		idx := pos.index()
		if lastIndex >= idx {
			t.Errorf("Position not monotonically increasing: %d >= %d", lastIndex, idx)
		}
		lastIndex = idx
	}
	if rec, err := rd.Next(); err != io.EOF {
		t.Fatalf("Unexpected Next record/error: %v %v", rec, err)
	}

	// Read all records by seeking to each position in reverse order
	for i := int(N - 1); i >= 0; i-- {
		p := positions[i]
		if err := rd.SeekToRecord(p); err != nil {
			t.Fatalf("Error seeking to record %d at %v: %v", i, p, err)
		}
		rec, err := rd.Next()
		if err != nil {
			t.Fatalf("Read error at %v: %v", p, err)
		} else if string(rec) != fmt.Sprintf("%d", i) {
			t.Errorf("At %v found: %s; expected: %d;", p, hex.EncodeToString(rec), i)
		}
	}
}

func TestReaderSeekKnownPositions(t *testing.T) {
	const N = 1e4
	buf := writeStrings(t, &WriterOptions{}, N)

	rd := NewReadSeeker(bytes.NewReader(buf.Bytes()))
	lastIndex := int64(-1)
	var positions []RecordPosition
	for i := 0; i < N; i++ {
		pos, err := rd.Position()
		if err != nil {
			t.Fatalf("Error getting position: %v", err)
		} else if _, err := rd.Next(); err != nil {
			t.Fatalf("Error reading sequentially: %v", err)
		}
		positions = append(positions, pos)
		idx := pos.index()
		if lastIndex >= idx {
			t.Errorf("Position not monotonically increasing: %d >= %d", lastIndex, idx)
		}
		lastIndex = idx
	}
	if rec, err := rd.Next(); err != io.EOF {
		t.Fatalf("Unexpected Next record/error: %v %v", rec, err)
	}

	// Read all records by seeking to each position in reverse order
	for i := int(N - 1); i >= 0; i-- {
		p := positions[i]
		if err := rd.Seek(p.index()); err != nil {
			t.Fatalf("Error seeking to record %d at %v (%d): %v", i, p, p.index(), err)
		}
		rec, err := rd.Next()
		if err != nil {
			t.Fatalf("Read error at %v: %v", p, err)
		} else if string(rec) != fmt.Sprintf("%d", i) {
			t.Errorf("At %v found: %s; expected: %d;", p, hex.EncodeToString(rec), i)
		}
	}
}

func TestReaderSeekAllPositions(t *testing.T) {
	const N = 1e4
	buf := writeStrings(t, &WriterOptions{}, N).Bytes()
	rd := NewReadSeeker(bytes.NewReader(buf))

	// Ensure every byte position is seekable
	var expected int
	for i := 0; i < len(buf); i++ {
		if err := rd.Seek(int64(i)); err != nil {
			t.Fatalf("Error seeking to %d/%d for %d: %v", i, len(buf), expected, err)
		}
		pos, err := rd.Position()
		if err != nil {
			t.Fatalf("Position error: %v", err)
		}
		rec, err := rd.Next()
		if expected == N-1 {
			if err != io.EOF {
				t.Fatalf("Read past end of file at %d (%v): %v %v", i, pos, rec, err)
			}
		} else if err != nil {
			t.Fatalf("Read error at %d/%d: %v; expected: %d", i, len(buf), err, expected)
		}

		if expected != N-1 && string(rec) != fmt.Sprintf("%d", expected) {
			expected++
			if string(rec) != fmt.Sprintf("%d", expected) {
				t.Fatalf("At %d/%d found: %s; expected: %d;", i, len(buf), string(rec), expected)
			}
		}
	}

	if expected != N-1 {
		t.Fatalf("Failed to read all known records: %d != %d", expected, int(N)-1)
	}
}

func TestRecordsMetadata(t *testing.T) {
	opts := &WriterOptions{
		Transpose:   true,
		Compression: BrotliCompression(4),
	}
	expected := &rmpb.RecordsMetadata{
		RecordWriterOptions: proto.String(opts.String()),
	}

	buf := writeStrings(t, opts, 128)
	rd := NewReader(bytes.NewReader(buf.Bytes()))

	found, err := rd.RecordsMetadata()
	if err != nil {
		log.Fatal(err)
	} else if diff := compare.ProtoDiff(found, expected); diff != "" {
		t.Errorf("Unexpected RecordsMetadata:  (-: found; +: expected)\n%s", diff)
	}
}

// TODO(schroederc): test transposed chunks
// TODO(schroederc): test padding
