/*
* Copyright 2018-2024 Open Networking Foundation (ONF) and the ONF Contributors

* 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 grpc

import (
	"context"
	"testing"

	"github.com/stretchr/testify/assert"
	"google.golang.org/grpc"
)

// A Mock Probe that returns the Ready member using the IsReady() func
type MockReadyProbe struct {
	Ready bool
}

func (m *MockReadyProbe) IsReady() bool {
	return m.Ready
}

// A Mock handler that returns the request as its result
func MockUnaryHandler(ctx context.Context, req interface{}) (interface{}, error) {
	_ = ctx
	return req, nil
}

func TestNewGrpcServer(t *testing.T) {
	server := NewGrpcServer("127.0.0.1:1234", nil, false, nil)
	assert.NotNil(t, server)
}

func TestMkServerInterceptorNoProbe(t *testing.T) {
	server := NewGrpcServer("127.0.0.1:1234", nil, false, nil)
	assert.NotNil(t, server)

	f := mkServerInterceptor(server)
	assert.NotNil(t, f)

	req := "SomeRequest"
	serverInfo := grpc.UnaryServerInfo{Server: nil, FullMethod: "somemethod"}

	result, err := f(context.Background(),
		req,
		&serverInfo,
		MockUnaryHandler)

	assert.Nil(t, err)
	assert.Equal(t, "SomeRequest", result)
}

func TestMkServerInterceptorReady(t *testing.T) {
	probe := &MockReadyProbe{Ready: true}

	server := NewGrpcServer("127.0.0.1:1234", nil, false, probe)
	assert.NotNil(t, server)

	f := mkServerInterceptor(server)
	assert.NotNil(t, f)

	req := "SomeRequest"
	serverInfo := grpc.UnaryServerInfo{Server: nil, FullMethod: "somemethod"}

	result, err := f(context.Background(),
		req,
		&serverInfo,
		MockUnaryHandler)

	assert.Nil(t, err)
	assert.NotNil(t, result)
}

func TestMkServerInterceptorNotReady(t *testing.T) {
	probe := &MockReadyProbe{Ready: false}

	server := NewGrpcServer("127.0.0.1:1234", nil, false, probe)
	assert.NotNil(t, server)

	f := mkServerInterceptor(server)
	assert.NotNil(t, f)

	req := "SomeRequest"
	serverInfo := grpc.UnaryServerInfo{Server: nil, FullMethod: "somemethod"}

	result, err := f(context.Background(),
		req,
		&serverInfo,
		MockUnaryHandler)

	assert.NotNil(t, err)
	assert.Nil(t, result)
}
