package regionserver

import (
	"context"
	"net/http"

	"github.com/go-resty/resty/v2"
	clusterdedicatedv1 "github.com/tidbcloud/infra-provider/api/tidbcloud/cluster-server/v1"

	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/entity"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

func (s *regionServerCliImpl) SetAuditLogConfiguration(
	ctx context.Context,
	region *entity.Region,
	req *clusterdedicatedv1.SetAuditLogConfigurationRequest,
) (*clusterdedicatedv1.AuditLogConfiguration, bizerr.BizError) {
	body, err := marshalOptions.Marshal(req)
	if err != nil {
		return nil, bizerr.New(bizerr.ErrCodeJsonMarshal, "%s", err.Error())
	}
	resp, berr := s.callRegion(
		ctx,
		region,
		http.MethodPost,
		operationMap["SetAuditLogConfiguration"],
		func(request *resty.Request) *resty.Request {
			request.SetPathParam(clusterIdParameter, req.GetClusterId())
			request.SetBody(body)
			return request
		},
	)
	if berr != nil {
		return nil, berr
	}

	var out clusterdedicatedv1.AuditLogConfiguration
	if err := unmarshalOptions.Unmarshal(resp.Body(), &out); err != nil {
		return nil, bizerr.New(bizerr.ErrCodeRegionalAPI, "%s", err.Error())
	}

	return &out, nil
}

func (s *regionServerCliImpl) GetAuditLogConfiguration(
	ctx context.Context,
	region *entity.Region,
	req *clusterdedicatedv1.GetAuditLogConfigurationRequest,
) (*clusterdedicatedv1.AuditLogConfiguration, bizerr.BizError) {
	resp, err := s.callRegion(
		ctx,
		region,
		http.MethodGet,
		operationMap["GetAuditLogConfiguration"],
		func(request *resty.Request) *resty.Request {
			request.SetPathParam(clusterIdParameter, req.GetClusterId())
			return request
		},
	)
	if err != nil {
		return nil, err
	}

	var out clusterdedicatedv1.AuditLogConfiguration
	if err := unmarshalOptions.Unmarshal(resp.Body(), &out); err != nil {
		return nil, bizerr.New(bizerr.ErrCodeRegionalAPI, "%s", err.Error())
	}

	return &out, nil
}

func (s *regionServerCliImpl) ValidateAuditLogConfiguration(
	ctx context.Context,
	region *entity.Region,
	in *clusterdedicatedv1.ValidateAuditLogConfigurationRequest,
) (*clusterdedicatedv1.ValidateAuditLogConfigurationResponse, bizerr.BizError) {
	body, err := marshalOptions.Marshal(in.AuditLogConfiguration)
	if err != nil {
		return nil, bizerr.New(bizerr.ErrCodeJsonMarshal, "%s", err.Error())
	}
	resp, berr := s.callRegion(
		ctx,
		region,
		http.MethodPut,
		operationMap["ValidateAuditLogConfiguration"],
		func(request *resty.Request) *resty.Request {
			request.SetPathParam(clusterIdParameter, in.GetClusterId())
			request.SetBody(body)
			return request
		},
	)
	if berr != nil {
		return nil, berr
	}

	var out clusterdedicatedv1.ValidateAuditLogConfigurationResponse
	if err := unmarshalOptions.Unmarshal(resp.Body(), &out); err != nil {
		return nil, bizerr.New(bizerr.ErrCodeRegionalAPI, "%s", err.Error())
	}

	return &out, nil
}

func (s *regionServerCliImpl) ListAuditLogs(
	ctx context.Context,
	region *entity.Region,
	in *clusterdedicatedv1.ListAuditLogsRequest,
) (*clusterdedicatedv1.ListAuditLogsResponse, bizerr.BizError) {
	body, err := marshalOptions.Marshal(in)
	if err != nil {
		return nil, bizerr.New(bizerr.ErrCodeJsonMarshal, "%s", err.Error())
	}
	resp, berr := s.callRegion(
		ctx,
		region,
		http.MethodPost,
		operationMap["ListAuditLogs"],
		func(request *resty.Request) *resty.Request {
			request.SetPathParam(clusterIdParameter, in.GetClusterId())
			request.SetBody(body)
			return request
		},
	)
	if berr != nil {
		return nil, berr
	}

	var out clusterdedicatedv1.ListAuditLogsResponse
	if err := unmarshalOptions.Unmarshal(resp.Body(), &out); err != nil {
		return nil, bizerr.New(bizerr.ErrCodeRegionalAPI, "%s", err.Error())
	}

	return &out, nil
}

func (s *regionServerCliImpl) GetAuditLogDownloadUrl(
	ctx context.Context,
	region *entity.Region,
	in *clusterdedicatedv1.GetAuditLogDownloadURLRequest,
) (*clusterdedicatedv1.GetAuditLogDownloadURLResponse, bizerr.BizError) {
	body, err := marshalOptions.Marshal(in)
	if err != nil {
		return nil, bizerr.New(bizerr.ErrCodeJsonMarshal, "%s", err.Error())
	}
	resp, berr := s.callRegion(
		ctx,
		region,
		http.MethodPost,
		operationMap["GetAuditLogDownloadUrl"],
		func(request *resty.Request) *resty.Request {
			request.SetPathParam(clusterIdParameter, in.GetClusterId())
			request.SetBody(body)
			return request
		},
	)
	if berr != nil {
		return nil, berr
	}

	var out clusterdedicatedv1.GetAuditLogDownloadURLResponse
	if err := unmarshalOptions.Unmarshal(resp.Body(), &out); err != nil {
		return nil, bizerr.New(bizerr.ErrCodeRegionalAPI, "%s", err.Error())
	}

	return &out, nil
}
