package sqluser

import (
	"context"

	"braces.dev/errtrace"

	globalserverlessv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/serverless/v1"
	"github.com/tidbcloud/tidb-management-service/serverless-global-service/domain/service/sqluser"
)

type service struct {
	sqlUserSvc sqluser.Service
}

func NewService(sqlUserSvc sqluser.Service) globalserverlessv1.SqlUserServiceServer {
	return &service{
		sqlUserSvc: sqlUserSvc,
	}
}

func (c *service) ChangeSqlUserPasswd(
	ctx context.Context,
	req *globalserverlessv1.ChangeSqlUserPasswdRequest,
) (*globalserverlessv1.ChangeSqlUserPasswdResponse, error) {
	err := c.sqlUserSvc.UpdateSqlUserPassword(ctx, req)
	if err != nil {
		return nil, errtrace.Wrap(err)
	}

	return &globalserverlessv1.ChangeSqlUserPasswdResponse{}, nil
}

func (c *service) CreateSqlUser(
	ctx context.Context,
	req *globalserverlessv1.SqlUserServiceCreateSqlUserRequest,
) (*globalserverlessv1.SqlUserServiceCreateSqlUserResponse, error) {
	err := c.sqlUserSvc.CreateSqlUser(ctx, req)
	if err != nil {
		return nil, errtrace.Wrap(err)
	}

	return &globalserverlessv1.SqlUserServiceCreateSqlUserResponse{}, nil
}

func (c *service) UpdateSqlUser(
	ctx context.Context,
	req *globalserverlessv1.SqlUserServiceUpdateSqlUserRequest,
) (*globalserverlessv1.SqlUserServiceUpdateSqlUserResponse, error) {
	err := c.sqlUserSvc.UpdateSqlUser(ctx, req)
	if err != nil {
		return nil, errtrace.Wrap(err)
	}

	return &globalserverlessv1.SqlUserServiceUpdateSqlUserResponse{}, nil
}

func (c *service) DeleteSqlUser(
	ctx context.Context,
	req *globalserverlessv1.SqlUserServiceDeleteSqlUserRequest,
) (*globalserverlessv1.SqlUserServiceDeleteSqlUserResponse, error) {
	err := c.sqlUserSvc.DeleteSqlUser(ctx, req)
	if err != nil {
		return nil, errtrace.Wrap(err)
	}

	return &globalserverlessv1.SqlUserServiceDeleteSqlUserResponse{}, nil
}

func (c *service) GetSqlUser(
	ctx context.Context,
	req *globalserverlessv1.SqlUserServiceGetSqlUserRequest,
) (*globalserverlessv1.SqlUserServiceGetSqlUserResponse, error) {
	user, err := c.sqlUserSvc.GetSqlUser(ctx, req)
	if err != nil {
		return nil, errtrace.Wrap(err)
	}

	return &globalserverlessv1.SqlUserServiceGetSqlUserResponse{
		User: user,
	}, nil
}

func (c *service) IsSqlUserExisting(
	ctx context.Context,
	req *globalserverlessv1.SqlUserServiceIsSqlUserExistingRequest,
) (*globalserverlessv1.SqlUserServiceIsSqlUserExistingResponse, error) {
	ok, err := c.sqlUserSvc.IsSqlUserExisting(ctx, req)
	if err != nil {
		return nil, errtrace.Wrap(err)
	}

	return &globalserverlessv1.SqlUserServiceIsSqlUserExistingResponse{
		Existing: ok,
	}, nil
}

func (c *service) CreateSqlRole(
	ctx context.Context,
	req *globalserverlessv1.SqlUserServiceCreateSqlRoleRequest,
) (*globalserverlessv1.SqlUserServiceCreateSqlRoleResponse, error) {
	err := c.sqlUserSvc.CreateSqlUserRole(ctx, req)
	if err != nil {
		return nil, errtrace.Wrap(err)
	}

	return &globalserverlessv1.SqlUserServiceCreateSqlRoleResponse{}, nil
}

func (c *service) UpdateSqlRole(
	ctx context.Context,
	req *globalserverlessv1.SqlUserServiceUpdateSqlRoleRequest,
) (*globalserverlessv1.SqlUserServiceUpdateSqlRoleResponse, error) {
	err := c.sqlUserSvc.UpdateSqlUserRole(ctx, req)
	if err != nil {
		return nil, errtrace.Wrap(err)
	}

	return &globalserverlessv1.SqlUserServiceUpdateSqlRoleResponse{}, nil
}

func (c *service) ListSqlUsers(
	ctx context.Context,
	req *globalserverlessv1.ListSqlUsersRequest,
) (*globalserverlessv1.ListSqlUsersResponse, error) {
	resultMap, dbUsers, err := c.sqlUserSvc.List(ctx, req)
	if err != nil {
		return nil, errtrace.Wrap(err)
	}

	return &globalserverlessv1.ListSqlUsersResponse{
		ResultMap: resultMap,
		DbUsers:   dbUsers,
	}, nil
}

func (c *service) RotateRootPassword(
	ctx context.Context,
	req *globalserverlessv1.RotateRootPasswordRequest,
) (*globalserverlessv1.RotateRootPasswordResponse, error) {
	resp, err := c.sqlUserSvc.RotateRootPassword(ctx, req)
	if err != nil {
		return nil, errtrace.Wrap(err)
	}
	return resp, nil
}

func (c *service) RedeemRootPassword(
	ctx context.Context,
	req *globalserverlessv1.RedeemRootPasswordRequest,
) (*globalserverlessv1.RedeemRootPasswordResponse, error) {
	resp, err := c.sqlUserSvc.RedeemRootPassword(ctx, req)
	if err != nil {
		return nil, errtrace.Wrap(err)
	}
	return resp, nil
}
