/*
 *
 * Copyright 2016 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.
 *
 *
 * Client used to test http2 error edge cases like GOAWAYs and RST_STREAMs
 *
 * Documentation:
 *	 https://github.com/grpc/grpc/blob/master/doc/negative-http2-interop-test-descriptions.md
 */

package main

import (
	"context"
	"flag"
	"net"
	"strconv"
	"sync"
	"time"

	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/grpclog"
	"google.golang.org/grpc/interop"
	testpb "google.golang.org/grpc/interop/grpc_testing"
	"google.golang.org/grpc/status"
)

var (
	serverHost = flag.String("server_host", "localhost", "The server host name")
	serverPort = flag.Int("server_port", 8080, "The server port number")
	testCase   = flag.String("test_case", "goaway",
		`Configure different test cases. Valid options are:
        goaway : client sends two requests, the server will send a goaway in between;
        rst_after_header : server will send rst_stream after it sends headers;
        rst_during_data : server will send rst_stream while sending data;
        rst_after_data : server will send rst_stream after sending data;
        ping : server will send pings between each http2 frame;
        max_streams : server will ensure that the max_concurrent_streams limit is upheld;`)
	largeReqSize  = 271828
	largeRespSize = 314159
)

func largeSimpleRequest() *testpb.SimpleRequest {
	pl := interop.ClientNewPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize)
	return &testpb.SimpleRequest{
		ResponseType: testpb.PayloadType_COMPRESSABLE,
		ResponseSize: int32(largeRespSize),
		Payload:      pl,
	}
}

// sends two unary calls. The server asserts that the calls use different connections.
func goaway(tc testpb.TestServiceClient) {
	interop.DoLargeUnaryCall(tc)
	// sleep to ensure that the client has time to recv the GOAWAY.
	// TODO(ncteisen): make this less hacky.
	time.Sleep(1 * time.Second)
	interop.DoLargeUnaryCall(tc)
}

func rstAfterHeader(tc testpb.TestServiceClient) {
	req := largeSimpleRequest()
	reply, err := tc.UnaryCall(context.Background(), req)
	if reply != nil {
		grpclog.Fatalf("Client received reply despite server sending rst stream after header")
	}
	if status.Code(err) != codes.Internal {
		grpclog.Fatalf("%v.UnaryCall() = _, %v, want _, %v", tc, status.Code(err), codes.Internal)
	}
}

func rstDuringData(tc testpb.TestServiceClient) {
	req := largeSimpleRequest()
	reply, err := tc.UnaryCall(context.Background(), req)
	if reply != nil {
		grpclog.Fatalf("Client received reply despite server sending rst stream during data")
	}
	if status.Code(err) != codes.Unknown {
		grpclog.Fatalf("%v.UnaryCall() = _, %v, want _, %v", tc, status.Code(err), codes.Unknown)
	}
}

func rstAfterData(tc testpb.TestServiceClient) {
	req := largeSimpleRequest()
	reply, err := tc.UnaryCall(context.Background(), req)
	if reply != nil {
		grpclog.Fatalf("Client received reply despite server sending rst stream after data")
	}
	if status.Code(err) != codes.Internal {
		grpclog.Fatalf("%v.UnaryCall() = _, %v, want _, %v", tc, status.Code(err), codes.Internal)
	}
}

func ping(tc testpb.TestServiceClient) {
	// The server will assert that every ping it sends was ACK-ed by the client.
	interop.DoLargeUnaryCall(tc)
}

func maxStreams(tc testpb.TestServiceClient) {
	interop.DoLargeUnaryCall(tc)
	var wg sync.WaitGroup
	for i := 0; i < 15; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			interop.DoLargeUnaryCall(tc)
		}()
	}
	wg.Wait()
}

func main() {
	flag.Parse()
	serverAddr := net.JoinHostPort(*serverHost, strconv.Itoa(*serverPort))
	var opts []grpc.DialOption
	opts = append(opts, grpc.WithInsecure())
	conn, err := grpc.Dial(serverAddr, opts...)
	if err != nil {
		grpclog.Fatalf("Fail to dial: %v", err)
	}
	defer conn.Close()
	tc := testpb.NewTestServiceClient(conn)
	switch *testCase {
	case "goaway":
		goaway(tc)
		grpclog.Infoln("goaway done")
	case "rst_after_header":
		rstAfterHeader(tc)
		grpclog.Infoln("rst_after_header done")
	case "rst_during_data":
		rstDuringData(tc)
		grpclog.Infoln("rst_during_data done")
	case "rst_after_data":
		rstAfterData(tc)
		grpclog.Infoln("rst_after_data done")
	case "ping":
		ping(tc)
		grpclog.Infoln("ping done")
	case "max_streams":
		maxStreams(tc)
		grpclog.Infoln("max_streams done")
	default:
		grpclog.Fatal("Unsupported test case: ", *testCase)
	}
}
