/*
 *
 * 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 test

import (
	"context"
	"net"
	"strings"
	"testing"
	"time"

	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/credentials/insecure"
	"google.golang.org/grpc/peer"
	"google.golang.org/grpc/status"

	testpb "google.golang.org/grpc/test/grpc_testing"
)

const defaultTestTimeout = 5 * time.Second

// testLegacyPerRPCCredentials is a PerRPCCredentials that has yet incorporated security level.
type testLegacyPerRPCCredentials struct{}

func (cr testLegacyPerRPCCredentials) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
	return nil, nil
}

func (cr testLegacyPerRPCCredentials) RequireTransportSecurity() bool {
	return true
}

func getSecurityLevel(ai credentials.AuthInfo) credentials.SecurityLevel {
	if c, ok := ai.(interface {
		GetCommonAuthInfo() credentials.CommonAuthInfo
	}); ok {
		return c.GetCommonAuthInfo().SecurityLevel
	}
	return credentials.InvalidSecurityLevel
}

// TestInsecureCreds tests the use of insecure creds on the server and client
// side, and verifies that expect security level and auth info are returned.
// Also verifies that this credential can interop with existing `WithInsecure`
// DialOption.
func (s) TestInsecureCreds(t *testing.T) {
	tests := []struct {
		desc                string
		clientInsecureCreds bool
		serverInsecureCreds bool
	}{
		{
			desc:                "client and server insecure creds",
			clientInsecureCreds: true,
			serverInsecureCreds: true,
		},
		{
			desc:                "client only insecure creds",
			clientInsecureCreds: true,
		},
		{
			desc:                "server only insecure creds",
			serverInsecureCreds: true,
		},
	}

	for _, test := range tests {
		t.Run(test.desc, func(t *testing.T) {
			ss := &stubServer{
				emptyCall: func(ctx context.Context, in *testpb.Empty) (*testpb.Empty, error) {
					if !test.serverInsecureCreds {
						return &testpb.Empty{}, nil
					}

					pr, ok := peer.FromContext(ctx)
					if !ok {
						return nil, status.Error(codes.DataLoss, "Failed to get peer from ctx")
					}
					// Check security level.
					secLevel := getSecurityLevel(pr.AuthInfo)
					if secLevel == credentials.InvalidSecurityLevel {
						return nil, status.Errorf(codes.Unauthenticated, "peer.AuthInfo does not implement GetCommonAuthInfo()")
					}
					if secLevel != credentials.NoSecurity {
						return nil, status.Errorf(codes.Unauthenticated, "Wrong security level: got %q, want %q", secLevel, credentials.NoSecurity)
					}
					return &testpb.Empty{}, nil
				},
			}

			sOpts := []grpc.ServerOption{}
			if test.serverInsecureCreds {
				sOpts = append(sOpts, grpc.Creds(insecure.NewCredentials()))
			}
			s := grpc.NewServer(sOpts...)
			defer s.Stop()

			testpb.RegisterTestServiceServer(s, ss)

			lis, err := net.Listen("tcp", "localhost:0")
			if err != nil {
				t.Fatalf("net.Listen(tcp, localhost:0) failed: %v", err)
			}

			go s.Serve(lis)

			addr := lis.Addr().String()
			ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
			defer cancel()
			cOpts := []grpc.DialOption{grpc.WithBlock()}
			if test.clientInsecureCreds {
				cOpts = append(cOpts, grpc.WithTransportCredentials(insecure.NewCredentials()))
			} else {
				cOpts = append(cOpts, grpc.WithInsecure())
			}
			cc, err := grpc.DialContext(ctx, addr, cOpts...)
			if err != nil {
				t.Fatalf("grpc.Dial(%q) failed: %v", addr, err)
			}
			defer cc.Close()

			c := testpb.NewTestServiceClient(cc)
			if _, err = c.EmptyCall(ctx, &testpb.Empty{}); err != nil {
				t.Fatalf("EmptyCall(_, _) = _, %v; want _, <nil>", err)
			}
		})
	}
}

func (s) TestInsecureCredsWithPerRPCCredentials(t *testing.T) {
	tests := []struct {
		desc                      string
		perRPCCredsViaDialOptions bool
		perRPCCredsViaCallOptions bool
		wantErr                   string
	}{
		{
			desc:                      "send PerRPCCredentials via DialOptions",
			perRPCCredsViaDialOptions: true,
			perRPCCredsViaCallOptions: false,
			wantErr:                   "context deadline exceeded",
		},
		{
			desc:                      "send PerRPCCredentials via CallOptions",
			perRPCCredsViaDialOptions: false,
			perRPCCredsViaCallOptions: true,
			wantErr:                   "transport: cannot send secure credentials on an insecure connection",
		},
	}
	for _, test := range tests {
		t.Run(test.desc, func(t *testing.T) {
			ss := &stubServer{
				emptyCall: func(ctx context.Context, in *testpb.Empty) (*testpb.Empty, error) {
					return &testpb.Empty{}, nil
				},
			}

			sOpts := []grpc.ServerOption{}
			sOpts = append(sOpts, grpc.Creds(insecure.NewCredentials()))
			s := grpc.NewServer(sOpts...)
			defer s.Stop()

			testpb.RegisterTestServiceServer(s, ss)

			lis, err := net.Listen("tcp", "localhost:0")
			if err != nil {
				t.Fatalf("net.Listen(tcp, localhost:0) failed: %v", err)
			}

			go s.Serve(lis)

			addr := lis.Addr().String()
			ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
			defer cancel()
			cOpts := []grpc.DialOption{grpc.WithBlock()}
			cOpts = append(cOpts, grpc.WithTransportCredentials(insecure.NewCredentials()))

			if test.perRPCCredsViaDialOptions {
				cOpts = append(cOpts, grpc.WithPerRPCCredentials(testLegacyPerRPCCredentials{}))
				if _, err := grpc.DialContext(ctx, addr, cOpts...); !strings.Contains(err.Error(), test.wantErr) {
					t.Fatalf("InsecureCredsWithPerRPCCredentials/send_PerRPCCredentials_via_DialOptions  = %v; want %s", err, test.wantErr)
				}
			}

			if test.perRPCCredsViaCallOptions {
				cc, err := grpc.DialContext(ctx, addr, cOpts...)
				if err != nil {
					t.Fatalf("grpc.Dial(%q) failed: %v", addr, err)
				}
				defer cc.Close()

				c := testpb.NewTestServiceClient(cc)
				if _, err = c.EmptyCall(ctx, &testpb.Empty{}, grpc.PerRPCCredentials(testLegacyPerRPCCredentials{})); !strings.Contains(err.Error(), test.wantErr) {
					t.Fatalf("InsecureCredsWithPerRPCCredentials/send_PerRPCCredentials_via_CallOptions  = %v; want %s", err, test.wantErr)
				}
			}
		})
	}
}
