/*
 *
 * Copyright 2021 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.
 *
 */

// Binary server is the server used for xDS interop tests.
package main

import (
	"context"
	"flag"
	"fmt"
	"log"
	"net"
	"os"

	"google.golang.org/grpc"
	"google.golang.org/grpc/admin"
	"google.golang.org/grpc/credentials/insecure"
	"google.golang.org/grpc/grpclog"
	"google.golang.org/grpc/health"
	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/reflection"
	"google.golang.org/grpc/xds"

	xdscreds "google.golang.org/grpc/credentials/xds"
	healthpb "google.golang.org/grpc/health/grpc_health_v1"
	testgrpc "google.golang.org/grpc/interop/grpc_testing"
	testpb "google.golang.org/grpc/interop/grpc_testing"
)

var (
	port            = flag.Int("port", 8080, "Listening port for test service")
	maintenancePort = flag.Int("maintenance_port", 8081, "Listening port for maintenance services like health, reflection, channelz etc when -secure_mode is true. When -secure_mode is false, all these services will be registered on -port")
	serverID        = flag.String("server_id", "go_server", "Server ID included in response")
	secureMode      = flag.Bool("secure_mode", false, "If true, retrieve security configuration from the management server. Else, use insecure credentials.")

	logger = grpclog.Component("interop")
)

func getHostname() string {
	hostname, err := os.Hostname()
	if err != nil {
		log.Fatalf("failed to get hostname: %v", err)
	}
	return hostname
}

// testServiceImpl provides an implementation of the TestService defined in
// grpc.testing package.
type testServiceImpl struct {
	testgrpc.UnimplementedTestServiceServer
	hostname string
}

func (s *testServiceImpl) EmptyCall(ctx context.Context, _ *testpb.Empty) (*testpb.Empty, error) {
	grpc.SetHeader(ctx, metadata.Pairs("hostname", s.hostname))
	return &testpb.Empty{}, nil
}

func (s *testServiceImpl) UnaryCall(ctx context.Context, in *testpb.SimpleRequest) (*testpb.SimpleResponse, error) {
	grpc.SetHeader(ctx, metadata.Pairs("hostname", s.hostname))
	return &testpb.SimpleResponse{ServerId: *serverID, Hostname: s.hostname}, nil
}

// xdsUpdateHealthServiceImpl provides an implementation of the
// XdsUpdateHealthService defined in grpc.testing package.
type xdsUpdateHealthServiceImpl struct {
	testgrpc.UnimplementedXdsUpdateHealthServiceServer
	healthServer *health.Server
}

func (x *xdsUpdateHealthServiceImpl) SetServing(_ context.Context, _ *testpb.Empty) (*testpb.Empty, error) {
	x.healthServer.SetServingStatus("", healthpb.HealthCheckResponse_SERVING)
	return &testpb.Empty{}, nil

}

func (x *xdsUpdateHealthServiceImpl) SetNotServing(_ context.Context, _ *testpb.Empty) (*testpb.Empty, error) {
	x.healthServer.SetServingStatus("", healthpb.HealthCheckResponse_NOT_SERVING)
	return &testpb.Empty{}, nil
}

func xdsServingModeCallback(addr net.Addr, args xds.ServingModeChangeArgs) {
	logger.Infof("Serving mode for xDS server at %s changed to %s", addr.String(), args.Mode)
	if args.Err != nil {
		logger.Infof("ServingModeCallback returned error: %v", args.Err)
	}
}

func main() {
	flag.Parse()

	if *secureMode && *port == *maintenancePort {
		logger.Fatal("-port and -maintenance_port must be different when -secure_mode is set")
	}

	testService := &testServiceImpl{hostname: getHostname()}
	healthServer := health.NewServer()
	updateHealthService := &xdsUpdateHealthServiceImpl{healthServer: healthServer}

	// If -secure_mode is not set, expose all services on -port with a regular
	// gRPC server.
	if !*secureMode {
		lis, err := net.Listen("tcp4", fmt.Sprintf(":%d", *port))
		if err != nil {
			logger.Fatalf("net.Listen(%s) failed: %v", fmt.Sprintf(":%d", *port), err)
		}

		server := grpc.NewServer()
		testgrpc.RegisterTestServiceServer(server, testService)
		healthServer.SetServingStatus("", healthpb.HealthCheckResponse_SERVING)
		healthpb.RegisterHealthServer(server, healthServer)
		testgrpc.RegisterXdsUpdateHealthServiceServer(server, updateHealthService)
		reflection.Register(server)
		cleanup, err := admin.Register(server)
		if err != nil {
			logger.Fatalf("Failed to register admin services: %v", err)
		}
		defer cleanup()
		if err := server.Serve(lis); err != nil {
			logger.Errorf("Serve() failed: %v", err)
		}
		return
	}

	// Create a listener on -port to expose the test service.
	testLis, err := net.Listen("tcp4", fmt.Sprintf(":%d", *port))
	if err != nil {
		logger.Fatalf("net.Listen(%s) failed: %v", fmt.Sprintf(":%d", *port), err)
	}

	// Create server-side xDS credentials with a plaintext fallback.
	creds, err := xdscreds.NewServerCredentials(xdscreds.ServerOptions{FallbackCreds: insecure.NewCredentials()})
	if err != nil {
		logger.Fatalf("Failed to create xDS credentials: %v", err)
	}

	// Create an xDS enabled gRPC server, register the test service
	// implementation and start serving.
	testServer := xds.NewGRPCServer(grpc.Creds(creds), xds.ServingModeCallback(xdsServingModeCallback))
	testgrpc.RegisterTestServiceServer(testServer, testService)
	go func() {
		if err := testServer.Serve(testLis); err != nil {
			logger.Errorf("test server Serve() failed: %v", err)
		}
	}()
	defer testServer.Stop()

	// Create a listener on -maintenance_port to expose other services.
	maintenanceLis, err := net.Listen("tcp4", fmt.Sprintf(":%d", *maintenancePort))
	if err != nil {
		logger.Fatalf("net.Listen(%s) failed: %v", fmt.Sprintf(":%d", *maintenancePort), err)
	}

	// Create a regular gRPC server and register the maintenance services on
	// it and start serving.
	maintenanceServer := grpc.NewServer()
	healthServer.SetServingStatus("", healthpb.HealthCheckResponse_SERVING)
	healthpb.RegisterHealthServer(maintenanceServer, healthServer)
	testgrpc.RegisterXdsUpdateHealthServiceServer(maintenanceServer, updateHealthService)
	reflection.Register(maintenanceServer)
	cleanup, err := admin.Register(maintenanceServer)
	if err != nil {
		logger.Fatalf("Failed to register admin services: %v", err)
	}
	defer cleanup()
	if err := maintenanceServer.Serve(maintenanceLis); err != nil {
		logger.Errorf("maintenance server Serve() failed: %v", err)
	}
}
