/*
 *
 * Copyright 2020 gRPC 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 resolver

import (
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
	"google.golang.org/grpc/internal/grpctest"
	"google.golang.org/grpc/internal/serviceconfig"
)

type s struct {
	grpctest.Tester
}

func Test(t *testing.T) {
	grpctest.RunSubTests(t, s{})
}

type fakeConfigSelector struct {
	selectConfig func(RPCInfo) (*RPCConfig, error)
}

func (f *fakeConfigSelector) SelectConfig(r RPCInfo) (*RPCConfig, error) {
	return f.selectConfig(r)
}

func (s) TestSafeConfigSelector(t *testing.T) {
	testRPCInfo := RPCInfo{Method: "test method"}

	retChan1 := make(chan *RPCConfig)
	retChan2 := make(chan *RPCConfig)

	one := 1
	two := 2

	resp1 := &RPCConfig{MethodConfig: serviceconfig.MethodConfig{MaxReqSize: &one}}
	resp2 := &RPCConfig{MethodConfig: serviceconfig.MethodConfig{MaxReqSize: &two}}

	cs1Called := make(chan struct{})
	cs2Called := make(chan struct{})

	cs1 := &fakeConfigSelector{
		selectConfig: func(r RPCInfo) (*RPCConfig, error) {
			cs1Called <- struct{}{}
			if diff := cmp.Diff(r, testRPCInfo); diff != "" {
				t.Errorf("SelectConfig(%v) called; want %v\n  Diffs:\n%s", r, testRPCInfo, diff)
			}
			return <-retChan1, nil
		},
	}
	cs2 := &fakeConfigSelector{
		selectConfig: func(r RPCInfo) (*RPCConfig, error) {
			cs2Called <- struct{}{}
			if diff := cmp.Diff(r, testRPCInfo); diff != "" {
				t.Errorf("SelectConfig(%v) called; want %v\n  Diffs:\n%s", r, testRPCInfo, diff)
			}
			return <-retChan2, nil
		},
	}

	scs := &SafeConfigSelector{}
	scs.UpdateConfigSelector(cs1)

	cs1Returned := make(chan struct{})
	go func() {
		got, err := scs.SelectConfig(testRPCInfo) // blocks until send to retChan1
		if err != nil || got != resp1 {
			t.Errorf("SelectConfig(%v) = %v, %v; want %v, nil", testRPCInfo, got, err, resp1)
		}
		close(cs1Returned)
	}()

	// cs1 is blocked but should be called
	select {
	case <-time.After(500 * time.Millisecond):
		t.Fatalf("timed out waiting for cs1 to be called")
	case <-cs1Called:
	}

	// swap in cs2 now that cs1 is called
	csSwapped := make(chan struct{})
	go func() {
		// wait awhile first to ensure cs1 could be called below.
		time.Sleep(50 * time.Millisecond)
		scs.UpdateConfigSelector(cs2) // Blocks until cs1 done
		close(csSwapped)
	}()

	// Allow cs1 to return and cs2 to eventually be swapped in.
	retChan1 <- resp1

	cs1Done := false // set when cs2 is first called
	for dl := time.Now().Add(150 * time.Millisecond); !time.Now().After(dl); {
		gotConfigChan := make(chan *RPCConfig)
		go func() {
			cfg, _ := scs.SelectConfig(testRPCInfo)
			gotConfigChan <- cfg
		}()
		select {
		case <-time.After(500 * time.Millisecond):
			t.Fatalf("timed out waiting for cs1 or cs2 to be called")
		case <-cs1Called:
			// Initially, before swapping to cs2, cs1 should be called
			retChan1 <- resp1
			go func() { <-gotConfigChan }()
			if cs1Done {
				t.Fatalf("cs1 called after cs2")
			}
		case <-cs2Called:
			// Success! the new config selector is being called
			if !cs1Done {
				select {
				case <-csSwapped:
				case <-time.After(50 * time.Millisecond):
					t.Fatalf("timed out waiting for UpdateConfigSelector to return")
				}
				select {
				case <-cs1Returned:
				case <-time.After(50 * time.Millisecond):
					t.Fatalf("timed out waiting for cs1 to return")
				}
				cs1Done = true
			}
			retChan2 <- resp2
			got := <-gotConfigChan
			if diff := cmp.Diff(got, resp2); diff != "" {
				t.Fatalf("SelectConfig(%v) = %v; want %v\n  Diffs:\n%s", testRPCInfo, got, resp2, diff)
			}
		}
		time.Sleep(10 * time.Millisecond)
	}
	if !cs1Done {
		t.Fatalf("timed out waiting for cs2 to be called")
	}
}
