package pd

import (
	"encoding/json"
	"fmt"
	"github.com/pingcap/schrodinger-test/once/drivers/pd/pd_ctl"
	"net/http"
	"net/http/httptest"
	"reflect"
	"testing"
)

func TestStoreInfo_AddScheduler(t *testing.T) {
	type fields struct {
		Store Store
	}
	type args struct {
		name string
	}
	tests := []struct {
		name    string
		fields  fields
		args    args
		wantErr bool
	}{
		{
			name:   "add-evict-leader-scheduler-to-store-1",
			fields: fields{Store: Store{ID: 1}},
			args:   args{name: "evict-leader-scheduler"},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			s := &StoreInfo{
				Store: tt.fields.Store,
			}
			ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				fmt.Fprintln(w, "")
			}))
			defer ts.Close()
			pd_ctl.Setup(nil, testBin, ts.URL)
			if err := s.AddScheduler(tt.args.name); (err != nil) != tt.wantErr {
				t.Errorf("AddScheduler() error = %v, wantErr %v", err, tt.wantErr)
			}
		})
	}
}

func TestStoreInfo_GetLeaders(t *testing.T) {
	type fields struct {
		Store Store
	}
	tests := []struct {
		name    string
		fields  fields
		want    []Region
		wantErr bool
	}{
		{
			name:   "get-leaders-from-store-1",
			fields: fields{Store: Store{ID: 1}},
			want: []Region{
				{
					ID: 1,
					Leader: Peer{
						ID:      1,
						StoreID: 1,
					},
				},
				{
					ID: 2,
					Leader: Peer{
						ID:      2,
						StoreID: 1,
					},
				},
			},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			s := &StoreInfo{
				Store: tt.fields.Store,
			}
			regionsInfo := RegionsInfo{
				Count:   len(tt.want),
				Regions: tt.want,
			}
			res, err := json.Marshal(regionsInfo)
			if err != nil {
				t.Errorf("Marshal regions info error = %v, regions info: %v", err, regionsInfo)
			}
			ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				fmt.Fprintln(w, string(res))
			}))
			defer ts.Close()
			pd_ctl.Setup(nil, testBin, ts.URL)
			got, err := s.GetLeaders()
			if (err != nil) != tt.wantErr {
				t.Errorf("GetLeaders() error = %v, wantErr %v", err, tt.wantErr)
				return
			}
			if !reflect.DeepEqual(got, tt.want) {
				t.Errorf("GetLeaders() got = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestStoreInfo_GetRegions(t *testing.T) {
	type fields struct {
		Store Store
	}
	tests := []struct {
		name    string
		fields  fields
		want    []Region
		wantErr bool
	}{
		{
			name:   "get-regions-from-store-1",
			fields: fields{Store: Store{ID: 1}},
			want: []Region{
				{
					ID: 1,
					Leader: Peer{
						ID:      1,
						StoreID: 1,
					},
				},
				{
					ID: 2,
					Leader: Peer{
						ID:      2,
						StoreID: 1,
					},
				},
			},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			s := &StoreInfo{
				Store: tt.fields.Store,
			}
			regionsInfo := RegionsInfo{
				Count:   len(tt.want),
				Regions: tt.want,
			}
			res, err := json.Marshal(regionsInfo)
			if err != nil {
				t.Errorf("Marshal regions info error = %v, regions info: %v", err, regionsInfo)
			}
			ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				fmt.Fprintln(w, string(res))
			}))
			defer ts.Close()
			pd_ctl.Setup(nil, testBin, ts.URL)
			got, err := s.GetRegions()
			if (err != nil) != tt.wantErr {
				t.Errorf("GetRegions() error = %v, wantErr %v", err, tt.wantErr)
				return
			}
			if !reflect.DeepEqual(got, tt.want) {
				t.Errorf("GetRegions() got = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestStoreInfo_RemoveScheduler(t *testing.T) {
	type fields struct {
		Store Store
	}
	type args struct {
		name string
	}
	tests := []struct {
		name    string
		fields  fields
		args    args
		wantErr bool
	}{
		{
			name:   "remove-evict-leader-scheduler",
			fields: fields{Store: Store{ID: 1}},
			args:   args{name: "evict-leader-scheduler"},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			s := &StoreInfo{
				Store: tt.fields.Store,
			}
			ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				fmt.Fprintln(w, "")
			}))
			defer ts.Close()
			pd_ctl.Setup(nil, testBin, ts.URL)
			if err := s.RemoveScheduler(tt.args.name); (err != nil) != tt.wantErr {
				t.Errorf("RemoveScheduler() error = %v, wantErr %v", err, tt.wantErr)
			}
		})
	}
}
