// Copyright 2015 The etcd Authors
//
// 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 rafthttp

import (
	"bytes"
	"encoding/binary"
	"io"
	"net/http"
	"reflect"
	"testing"

	"github.com/coreos/etcd/raft/raftpb"
	"github.com/coreos/etcd/version"
	"github.com/coreos/go-semver/semver"
)

func TestEntry(t *testing.T) {
	tests := []raftpb.Entry{
		{},
		{Term: 1, Index: 1},
		{Term: 1, Index: 1, Data: []byte("some data")},
	}
	for i, tt := range tests {
		b := &bytes.Buffer{}
		if err := writeEntryTo(b, &tt); err != nil {
			t.Errorf("#%d: unexpected write ents error: %v", i, err)
			continue
		}
		var ent raftpb.Entry
		if err := readEntryFrom(b, &ent); err != nil {
			t.Errorf("#%d: unexpected read ents error: %v", i, err)
			continue
		}
		if !reflect.DeepEqual(ent, tt) {
			t.Errorf("#%d: ent = %+v, want %+v", i, ent, tt)
		}
	}
}

func TestCompareMajorMinorVersion(t *testing.T) {
	tests := []struct {
		va, vb *semver.Version
		w      int
	}{
		// equal to
		{
			semver.Must(semver.NewVersion("2.1.0")),
			semver.Must(semver.NewVersion("2.1.0")),
			0,
		},
		// smaller than
		{
			semver.Must(semver.NewVersion("2.0.0")),
			semver.Must(semver.NewVersion("2.1.0")),
			-1,
		},
		// bigger than
		{
			semver.Must(semver.NewVersion("2.2.0")),
			semver.Must(semver.NewVersion("2.1.0")),
			1,
		},
		// ignore patch
		{
			semver.Must(semver.NewVersion("2.1.1")),
			semver.Must(semver.NewVersion("2.1.0")),
			0,
		},
		// ignore prerelease
		{
			semver.Must(semver.NewVersion("2.1.0-alpha.0")),
			semver.Must(semver.NewVersion("2.1.0")),
			0,
		},
	}
	for i, tt := range tests {
		if g := compareMajorMinorVersion(tt.va, tt.vb); g != tt.w {
			t.Errorf("#%d: compare = %d, want %d", i, g, tt.w)
		}
	}
}

func TestServerVersion(t *testing.T) {
	tests := []struct {
		h  http.Header
		wv *semver.Version
	}{
		// backward compatibility with etcd 2.0
		{
			http.Header{},
			semver.Must(semver.NewVersion("2.0.0")),
		},
		{
			http.Header{"X-Server-Version": []string{"2.1.0"}},
			semver.Must(semver.NewVersion("2.1.0")),
		},
		{
			http.Header{"X-Server-Version": []string{"2.1.0-alpha.0+git"}},
			semver.Must(semver.NewVersion("2.1.0-alpha.0+git")),
		},
	}
	for i, tt := range tests {
		v := serverVersion(tt.h)
		if v.String() != tt.wv.String() {
			t.Errorf("#%d: version = %s, want %s", i, v, tt.wv)
		}
	}
}

func TestMinClusterVersion(t *testing.T) {
	tests := []struct {
		h  http.Header
		wv *semver.Version
	}{
		// backward compatibility with etcd 2.0
		{
			http.Header{},
			semver.Must(semver.NewVersion("2.0.0")),
		},
		{
			http.Header{"X-Min-Cluster-Version": []string{"2.1.0"}},
			semver.Must(semver.NewVersion("2.1.0")),
		},
		{
			http.Header{"X-Min-Cluster-Version": []string{"2.1.0-alpha.0+git"}},
			semver.Must(semver.NewVersion("2.1.0-alpha.0+git")),
		},
	}
	for i, tt := range tests {
		v := minClusterVersion(tt.h)
		if v.String() != tt.wv.String() {
			t.Errorf("#%d: version = %s, want %s", i, v, tt.wv)
		}
	}
}

func TestCheckVersionCompatibility(t *testing.T) {
	ls := semver.Must(semver.NewVersion(version.Version))
	lmc := semver.Must(semver.NewVersion(version.MinClusterVersion))
	tests := []struct {
		server     *semver.Version
		minCluster *semver.Version
		wok        bool
	}{
		// the same version as local
		{
			ls,
			lmc,
			true,
		},
		// one version lower
		{
			lmc,
			&semver.Version{},
			true,
		},
		// one version higher
		{
			&semver.Version{Major: ls.Major + 1},
			ls,
			true,
		},
		// too low version
		{
			&semver.Version{Major: lmc.Major - 1},
			&semver.Version{},
			false,
		},
		// too high version
		{
			&semver.Version{Major: ls.Major + 1, Minor: 1},
			&semver.Version{Major: ls.Major + 1},
			false,
		},
	}
	for i, tt := range tests {
		err := checkVersionCompability("", tt.server, tt.minCluster)
		if ok := err == nil; ok != tt.wok {
			t.Errorf("#%d: ok = %v, want %v", i, ok, tt.wok)
		}
	}
}

func writeEntryTo(w io.Writer, ent *raftpb.Entry) error {
	size := ent.Size()
	if err := binary.Write(w, binary.BigEndian, uint64(size)); err != nil {
		return err
	}
	b, err := ent.Marshal()
	if err != nil {
		return err
	}
	_, err = w.Write(b)
	return err
}

func readEntryFrom(r io.Reader, ent *raftpb.Entry) error {
	var l uint64
	if err := binary.Read(r, binary.BigEndian, &l); err != nil {
		return err
	}
	buf := make([]byte, int(l))
	if _, err := io.ReadFull(r, buf); err != nil {
		return err
	}
	return ent.Unmarshal(buf)
}
