package mapping

import (
	"context"

	commonsemantic "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/commonv1"
	semantic "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/federatedloginv1"
	runtimev1 "github.com/pingcap-inc/nexuscrm-contract/wire-go/gen/runtime/v1"
)

func ToWireBeginFederatedLoginRequest(ctx context.Context, request semantic.BeginRequest) (*runtimev1.BeginFederatedLoginRequest, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateBeginRequest(ctx, request); err != nil {
		return nil, err
	}
	return &runtimev1.BeginFederatedLoginRequest{
		AppInstallationId: request.AppInstallationID,
		RedirectUri:       request.RedirectURI,
	}, nil
}

func FromWireBeginFederatedLoginRequest(ctx context.Context, request *runtimev1.BeginFederatedLoginRequest) (semantic.BeginRequest, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return semantic.BeginRequest{}, err
	}
	if request == nil {
		return semantic.BeginRequest{}, &semantic.Failure{
			Category: semantic.FailureInvalidRequest, InvalidComponent: commonsemantic.InvalidComponentResponse,
		}
	}
	value := semantic.BeginRequest{
		AppInstallationID: request.GetAppInstallationId(),
		RedirectURI:       request.GetRedirectUri(),
	}
	return value, semantic.ValidateBeginRequest(ctx, value)
}

func ToWireBeginFederatedLoginResponse(response semantic.BeginResponse) (*runtimev1.BeginFederatedLoginResponse, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateBeginResponse(response); err != nil {
		return nil, err
	}
	return &runtimev1.BeginFederatedLoginResponse{
		State: response.State, ExpiresAtUnixSecond: response.ExpiresAtUnixSecond,
	}, nil
}

func FromWireBeginFederatedLoginResponse(response *runtimev1.BeginFederatedLoginResponse) (semantic.BeginResponse, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return semantic.BeginResponse{}, err
	}
	if response == nil {
		return semantic.BeginResponse{}, &semantic.Failure{Category: semantic.FailureInternal}
	}
	value := semantic.BeginResponse{
		State: response.GetState(), ExpiresAtUnixSecond: response.GetExpiresAtUnixSecond(),
	}
	return value, semantic.ValidateBeginResponse(value)
}

func ToWireConsumeFederatedLoginRequest(ctx context.Context, request semantic.ConsumeRequest) (*runtimev1.ConsumeFederatedLoginRequest, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateConsumeRequest(ctx, request); err != nil {
		return nil, err
	}
	return &runtimev1.ConsumeFederatedLoginRequest{
		AppInstallationId: request.AppInstallationID,
		State:             request.State,
		RedirectUri:       request.RedirectURI,
	}, nil
}

func FromWireConsumeFederatedLoginRequest(ctx context.Context, request *runtimev1.ConsumeFederatedLoginRequest) (semantic.ConsumeRequest, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return semantic.ConsumeRequest{}, err
	}
	if request == nil {
		return semantic.ConsumeRequest{}, &semantic.Failure{
			Category: semantic.FailureInvalidRequest, InvalidComponent: commonsemantic.InvalidComponentResponse,
		}
	}
	value := semantic.ConsumeRequest{
		AppInstallationID: request.GetAppInstallationId(),
		State:             request.GetState(),
		RedirectURI:       request.GetRedirectUri(),
	}
	return value, semantic.ValidateConsumeRequest(ctx, value)
}

func ToWireConsumeFederatedLoginResponse(response semantic.ConsumeResponse) (*runtimev1.ConsumeFederatedLoginResponse, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateConsumeResponse(response); err != nil {
		return nil, err
	}
	return &runtimev1.ConsumeFederatedLoginResponse{}, nil
}

func FromWireConsumeFederatedLoginResponse(response *runtimev1.ConsumeFederatedLoginResponse) (semantic.ConsumeResponse, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return semantic.ConsumeResponse{}, err
	}
	if response == nil {
		return semantic.ConsumeResponse{}, &semantic.Failure{Category: semantic.FailureInternal}
	}
	value := semantic.ConsumeResponse{}
	return value, semantic.ValidateConsumeResponse(value)
}
