/*
 *
 * 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/internal/stubserver"
	"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.StubServer{
				EmptyCallF: 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.StubServer{
				EmptyCallF: 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)
				}
			}
		})
	}
}
