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

import (
	"context"
	"net"

	"github.com/cloudwego/kitex/pkg/endpoint"
	"github.com/cloudwego/kitex/pkg/rpcinfo"
	"github.com/cloudwego/kitex/pkg/streaming"
)

// ClientTransHandlerFactory to new TransHandler for client
type ClientTransHandlerFactory interface {
	NewTransHandler(opt *ClientOption) (ClientTransHandler, error)
}

// ServerTransHandlerFactory to new TransHandler for server
type ServerTransHandlerFactory interface {
	NewTransHandler(opt *ServerOption) (ServerTransHandler, error)
}

// TransReadWriter .
type TransReadWriter interface {
	Write(ctx context.Context, conn net.Conn, send Message) (nctx context.Context, err error)
	Read(ctx context.Context, conn net.Conn, msg Message) (nctx context.Context, err error)
}

// TransHandler is similar to the handler role in netty
// Transport can be refactored to support pipeline, and then is able to support other extensions at conn level.
type TransHandler interface {
	TransReadWriter
	OnInactive(ctx context.Context, conn net.Conn)
	OnError(ctx context.Context, err error, conn net.Conn)
	OnMessage(ctx context.Context, args, result Message) (context.Context, error)
	SetPipeline(pipeline *TransPipeline)
}

// ClientTransHandler is just TransHandler.
type ClientTransHandler interface {
	TransHandler
}

// ServerTransHandler have some new functions.
type ServerTransHandler interface {
	TransHandler
	OnActive(ctx context.Context, conn net.Conn) (context.Context, error)
	OnRead(ctx context.Context, conn net.Conn) error
}

// InvokeHandleFuncSetter is used to set invoke handle func.
type InvokeHandleFuncSetter interface {
	SetInvokeHandleFunc(inkHdlFunc endpoint.Endpoint)
}

// GracefulShutdown supports closing connections in a graceful manner.
type GracefulShutdown interface {
	GracefulShutdown(ctx context.Context) error
}

// ClientStreamFactory is used to create a stream for client.
// NOTICE: might be updated without compatibility guarantee in the future.
type ClientStreamFactory interface {
	NewStream(ctx context.Context, ri rpcinfo.RPCInfo) (streaming.ClientStream, error)
}
