/*
 *
 * 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 xds_test contains e2e tests for xDS use on the server.
package xds_test

import (
	"context"
	"fmt"
	"io/ioutil"
	"os"
	"path"
	"testing"
	"time"

	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/types/known/anypb"

	v2discoverypb "github.com/envoyproxy/go-control-plane/envoy/api/v2"
	v3corepb "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
	v3listenerpb "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
	v3httppb "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	"google.golang.org/grpc/internal/grpctest"
	testpb "google.golang.org/grpc/test/grpc_testing"
	"google.golang.org/grpc/xds"
	"google.golang.org/grpc/xds/internal/env"
	"google.golang.org/grpc/xds/internal/testutils/fakeserver"
	"google.golang.org/grpc/xds/internal/version"
)

const (
	defaultTestTimeout = 10 * time.Second
	localAddress       = "localhost:9999"
	listenerName       = "grpc/server?udpa.resource.listening_address=localhost:9999"
)

type s struct {
	grpctest.Tester
}

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

func setupListenerResponse(respCh chan *fakeserver.Response, name string) {
	respCh <- &fakeserver.Response{
		Resp: &v2discoverypb.DiscoveryResponse{
			Resources: []*anypb.Any{
				{
					TypeUrl: version.V2ListenerURL,
					Value: func() []byte {
						l := &v3listenerpb.Listener{
							// This needs to match the name we are querying for.
							Name: listenerName,
							ApiListener: &v3listenerpb.ApiListener{
								ApiListener: &anypb.Any{
									TypeUrl: version.V2HTTPConnManagerURL,
									Value: func() []byte {
										cm := &v3httppb.HttpConnectionManager{
											RouteSpecifier: &v3httppb.HttpConnectionManager_Rds{
												Rds: &v3httppb.Rds{
													ConfigSource: &v3corepb.ConfigSource{
														ConfigSourceSpecifier: &v3corepb.ConfigSource_Ads{Ads: &v3corepb.AggregatedConfigSource{}},
													},
													RouteConfigName: "route-config",
												},
											},
										}
										mcm, _ := proto.Marshal(cm)
										return mcm
									}(),
								},
							},
						}
						ml, _ := proto.Marshal(l)
						return ml
					}(),
				},
			},
			TypeUrl: version.V2ListenerURL,
		},
	}
}

func setupBootstrapFile(t *testing.T, serverURI string) func() {
	// Create a bootstrap file in a temporary directory.
	tmpdir, err := ioutil.TempDir("", "xds-server-test*")
	if err != nil {
		t.Fatalf("failed to create tempdir: %v", err)
	}
	bootstrapContents := fmt.Sprintf(`
		{
			"node": {
				"id": "ENVOY_NODE_ID",
				"metadata": {
				    "TRAFFICDIRECTOR_GRPC_HOSTNAME": "trafficdirector"
			    }
			},
			"xds_servers" : [{
				"server_uri": "%s",
				"channel_creds": [
					{ "type": "insecure" }
				]
			}]
		}`, serverURI)
	bootstrapFileName := path.Join(tmpdir, "bootstrap")
	if err := ioutil.WriteFile(bootstrapFileName, []byte(bootstrapContents), os.ModePerm); err != nil {
		t.Fatalf("failed to write bootstrap file: %v", err)
	}

	origBootstrapFileName := env.BootstrapFileName
	env.BootstrapFileName = bootstrapFileName
	t.Logf("Create bootstrap file at %s with contents\n%s", bootstrapFileName, bootstrapContents)
	return func() { env.BootstrapFileName = origBootstrapFileName }
}

// TestServerSideXDS is an e2e tests for xDS use on the server. This does not
// use any xDS features because we have not implemented any on the server side.
func (s) TestServerSideXDS(t *testing.T) {
	// Spin up a fake xDS management server on a local port.
	// TODO(easwars): Switch to using the server from envoy-go-control-plane.
	fs, cleanup, err := fakeserver.StartServer()
	if err != nil {
		t.Fatalf("failed to start fake xDS server: %v", err)
	}
	defer cleanup()
	t.Logf("Started xDS management server at %s", fs.Address)

	// Create a bootstrap file in a temporary directory.
	defer setupBootstrapFile(t, fs.Address)()

	// Initialize a gRPC server which uses xDS, and register stubServer on it.
	server := xds.NewGRPCServer()
	testpb.RegisterTestServiceServer(server, &testService{})
	defer server.Stop()

	go func() {
		opts := xds.ServeOptions{Network: "tcp", Address: localAddress}
		if err := server.Serve(opts); err != nil {
			t.Errorf("Serve(%+v) failed: %v", opts, err)
		}
	}()

	// Create a ClientConn and make a successful RPC.
	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
	defer cancel()

	// Setup the fake management server to respond with a Listener resource.
	go func() {
		if _, err := fs.XDSRequestChan.Receive(ctx); err != nil {
			t.Errorf("timeout when waiting for listener request: %v", err)
		}
		setupListenerResponse(fs.XDSResponseChan, listenerName)
	}()

	cc, err := grpc.DialContext(ctx, localAddress, grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		t.Fatalf("failed to dial local test server: %v", err)
	}
	defer cc.Close()

	client := testpb.NewTestServiceClient(cc)
	if _, err := client.EmptyCall(ctx, &testpb.Empty{}, grpc.WaitForReady(true)); err != nil {
		t.Fatalf("rpc EmptyCall() failed: %v", err)
	}
}

type testService struct {
	testpb.TestServiceServer
}

func (*testService) EmptyCall(context.Context, *testpb.Empty) (*testpb.Empty, error) {
	return &testpb.Empty{}, nil
}
