package eccr

import (
	"encoding/base64"
	"strconv"

	"github.com/baidubce/bce-sdk-go/bce"
	"github.com/baidubce/bce-sdk-go/http"
)

type Interface interface {
	ListInstances(args *ListInstancesArgs) (*ListInstancesResponse, error)
	GetInstanceDetail(instanceID string) (*GetInstanceDetailResponse, error)
	CreateInstance(args *CreateInstanceArgs) (*CreateInstanceResponse, error)
	RenewInstance(orderType string, args *RenewInstanceArgs) (*RenewInstanceResponse, error)
	UpdateInstance(instanceID string, args *UpdateInstanceArgs) (*UpdateInstanceResponse, error)
	UpgradeInstance(instanceID string, args *UpgradeInstanceArgs) (*UpgradeInstanceResponse, error)
	ListPrivateNetworks(instanceID string) (*ListPrivateNetworksResponse, error)
	CreatePrivateNetwork(instanceID string, args *CreatePrivateNetworkArgs) (map[string]string, error)
	DeletePrivateNetwork(instanceID string, args *DeletePrivateNetworkArgs) error
	ListPublicNetworks(instanceID string) (*ListPublicNetworksResponse, error)
	UpdatePublicNetwork(instanceID string, args *UpdatePublicNetworkArgs) error
	DeletePublicNetworkWhitelist(instanceID string, args *DeletePublicNetworkWhitelistArgs) error
	AddPublicNetworkWhitelist(instanceID string, args *AddPublicNetworkWhitelistArgs) error
	ResetPassword(instanceID string, args *ResetPasswordArgs) (map[string]string, error)
	CreateTemporaryToken(instanceID string, args *CreateTemporaryTokenArgs) (*CreateTemporaryTokenResponse, error)
	CreateRegistry(instanceID string, args *CreateRegistryArgs) (*CreateRegistryResponse, error)
	GetRegistryDetail(instanceID, registryID string) (*RegistryResponse, error)
	ListRegistries(instanceID string, args *ListRegistriesArgs) (*ListRegistriesResponse, error)
	CheckHealthRegistry(instanceID string, args *RegistryRequestArgs) error
	UpdateRegistry(instanceID, registryID string, args *RegistryRequestArgs) (*RegistryResponse, error)
	DeleteRegistry(instanceID, registryID string) error
	ListProjects(instanceID string, args *ListProjectsArgs) (*ListProjectsResponse, error)
	CreateProject(instanceID string, args *CreateProjectArgs) (*ProjectResponse, error)
	GetProjectDetail(instanceID, projectName string) (*ProjectResponse, error)
	DeleteProject(instanceID, projectName string) error
	BatchDeleteProjects(instanceID string, args *BatchDeleteProjectsArgs) error
	ListRepositories(instanceID, projectName string, args *ListRepositoriesArgs) (*ListRepositoriesResponse, error)
	GetRepositoryDetail(instanceID, projectName, repositoryName string) (*RepositoryResponse, error)
	UpdateRepository(instanceID, projectName, repositoryName string, args *UpdateRepositoryArgs) (*RepositoryResponse, error)
	DeleteRepository(instanceID, projectName, repositoryName string) error
	BatchDeleteRepositories(instanceID, projectName string, args *BatchDeleteRepositoriesArgs) error
	ListTags(instanceID, projectName, repositoryName string, args *ListTagsArgs) (*ListTagsResponse, error)
	GetTagDetail(instanceID, projectName, repositoryName, tagName string) (*ImageTag, error)
	DeleteTag(instanceID, projectName, repositoryName, tagName string) error
	BatchDeleteTags(instanceID, projectName, repositoryName string, args *BatchDeleteTagsArgs) error
	ListRobots(instanceID string, args *ListRobotsArgs) (*ListRobotsResponse, error)
	CreateRobot(instanceID string, args *CreateRobotArgs) (*RobotResponse, error)
	UpdateRobot(instanceID, robotID string, args *UpdateRobotArgs) error
	DeleteRobot(instanceID, robotID string) error
	RefreshRobotSecret(instanceID, robotID string, args *RefreshRobotSecretArgs) (*RobotTokenResponse, error)
	ListBuildRepositoryTask(instanceID, projectName, repositoryName string, args *ListBuildRepositoryTaskArgs) (*ListBuildRepositoryTaskResponse, error)
	CreateBuildRepositoryTask(instanceID, projectName, repositoryName string, args *BuildRepositoryTaskArgs) (*BuildRepositoryTaskResponse, error)
	GetBuildRepositoryTask(instanceID, projectName, repositoryName, imageBuildID string) (*BuildRepositoryTaskResult, error)
	DeleteBuildRepositoryTask(instanceID, projectName, repositoryName, imageBuildID string) error
	BatchDeleteBuildRepositoryTask(instanceID, projectName, repositoryName string, args *BatchDeleteBuildRepositoryTaskArgs) error
	AssignInstanceTag(instanceID string, args *AssignTagsRequest) error
}

// ListInstances - list all instance with the specific parameters
//
// PARAMS:
//   - ListInstancesArgs: the arguments to list all instance
//
// RETURNS:
//   - ListInstancesResponse: the result of list Instance
//   - error: nil if success otherwise the specific error
func (c *Client) ListInstances(args *ListInstancesArgs) (*ListInstancesResponse, error) {

	result := &ListInstancesResponse{}
	err := bce.NewRequestBuilder(c).
		WithMethod(http.GET).
		WithURL(getInstanceListURI()).
		WithQueryParamFilter("keywordType", args.KeywordType).
		WithQueryParamFilter("keyword", args.Keyword).
		WithQueryParamFilter("pageNo", strconv.Itoa(args.PageNo)).
		WithQueryParamFilter("pageSize", strconv.Itoa(args.PageSize)).
		WithQueryParamFilter("acrossregion", args.Acrossregion).
		WithResult(result).
		Do()

	return result, err
}

// GetInstanceDetail - get a specific instance detail info
//
// PARAMS:
//   - instanceID: the specific instance ID
//
// RETURNS:
//   - *GetInstanceDetailResponse: the result of get instance detail info
//   - error: nil if success otherwise the specific error
func (c *Client) GetInstanceDetail(instanceID string) (*GetInstanceDetailResponse, error) {

	result := &GetInstanceDetailResponse{}
	err := bce.NewRequestBuilder(c).
		WithMethod(http.GET).
		WithURL(getInstanceURI(instanceID)).
		WithResult(result).
		Do()

	return result, err
}

// CreateInstance - create instance with the specific parameters
//
// PARAMS:
//   - CreateInstanceArgs: the arguments to crate Instance
//
// RETURNS:
//   - CreateInstanceResponse: the result of create Instance
//   - error: nil if success otherwise the specific error
func (c *Client) CreateInstance(args *CreateInstanceArgs) (*CreateInstanceResponse, error) {
	result := &CreateInstanceResponse{}

	err := bce.NewRequestBuilder(c).
		WithMethod(http.POST).
		WithURL(getInstanceCreateURI()).
		WithResult(result).
		WithBody(args).
		Do()

	return result, err
}

// RenewInstance - create instance with the specific parameters
//
// PARAMS:
//   - orderType: the operation type, value requires renew
//   - ConfirmOrderRequest: the arguments to crate Instance
//
// RETURNS:
//   - CreateInstanceResponse: the result of create Instance
//   - error: nil if success otherwise the specific error
func (c *Client) RenewInstance(orderType string, args *RenewInstanceArgs) (*RenewInstanceResponse, error) {
	result := &RenewInstanceResponse{}

	err := bce.NewRequestBuilder(c).
		WithMethod(http.POST).
		WithQueryParamFilter("orderType", orderType).
		WithURL(getInstanceRenewURI()).
		WithBody(args).
		WithResult(result).
		Do()

	return result, err
}

// UpdateInstance - update instance info
//
// PARAMS:
//   - instanceId: the specific instance ID
//   - UpdateInstanceArgs: parameters required to update instance info
//
// RETURNS:
//   - *UpdateInstanceResponse: the result of updated instance info
//   - error: nil if success otherwise the specific error
func (c *Client) UpdateInstance(instanceID string, args *UpdateInstanceArgs) (*UpdateInstanceResponse, error) {
	result := &UpdateInstanceResponse{}

	err := bce.NewRequestBuilder(c).
		WithMethod(http.PUT).
		WithURL(getInstanceURI(instanceID)).
		WithBody(args).
		WithResult(result).
		Do()

	return result, err
}

// UpgradeInstance - upgrade instance by specific parameters
//
// PARAMS:
//   - instanceId: the specific instance ID
//   - UpgradeInstanceArgs: parameters required to upgrade instance information
//
// RETURNS:
//
//	= UpgradeInstanceResponse: the result of upgrade instance
//	- error: nil if success otherwise the specific error
func (c *Client) UpgradeInstance(instanceID string, args *UpgradeInstanceArgs) (*UpgradeInstanceResponse, error) {
	result := &UpgradeInstanceResponse{}

	err := bce.NewRequestBuilder(c).WithMethod(http.PUT).
		WithURL(getInstanceUpgradeURI(instanceID)).
		WithBody(args).
		WithResult(result).
		Do()

	return result, err
}

// ListPrivateNetworks - list all Privatelinks in an instance with the specific parameters
//
// PARAMS:
//   - instanceID: the specific instance ID
//
// RETURNS:
//   - *ListPrivateNetworksResponse: the result of list Privatelinks
//   - error: nil if success otherwise the specific error
func (c *Client) ListPrivateNetworks(instanceID string) (*ListPrivateNetworksResponse, error) {
	result := &ListPrivateNetworksResponse{}
	err := bce.NewRequestBuilder(c).
		WithMethod(http.GET).
		WithURL(getPrivateNetworkListResponseURI(instanceID)).
		WithResult(result).
		Do()

	return result, err
}

// CreatePrivateNetwork - create private Network with the specific parameters
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - CreateInstanceArgs: the arguments to crate private network
//
// RETURNS:
//   - error: nil if success otherwise the specific error
func (c *Client) CreatePrivateNetwork(instanceID string, args *CreatePrivateNetworkArgs) (map[string]string, error) {
	result := make(map[string]string)

	err := bce.NewRequestBuilder(c).
		WithMethod(http.POST).
		WithURL(getPrivateNetworkResponseURI(instanceID)).
		WithBody(args).
		WithResult(result).
		Do()

	return result, err
}

// DeletePrivateNetwork - delete private Network with the specific parameters
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - DeletePrivateNetworkArgs: the arguments to delete private network
//
// RETURNS:
//   - error: nil if success otherwise the specific error
func (c *Client) DeletePrivateNetwork(instanceID string, args *DeletePrivateNetworkArgs) error {

	err := bce.NewRequestBuilder(c).
		WithMethod(http.DELETE).
		WithURL(getPrivateNetworkResponseURI(instanceID)).
		WithBody(args).
		Do()

	return err
}

// ListPublicNetworks - list all Publiclinks in an instance with the specific parameters
//
// PARAMS:
//   - instanceID: the specific instance ID
//
// RETURNS:
//   - *ListPublicNetworksResponse: the result of list Publiclinks
//   - error: nil if success otherwise the specific error
func (c *Client) ListPublicNetworks(instanceID string) (*ListPublicNetworksResponse, error) {
	result := &ListPublicNetworksResponse{}

	err := bce.NewRequestBuilder(c).
		WithMethod(http.GET).
		WithURL(getPublicNetworkResponseURI(instanceID)).
		WithResult(result).Do()

	return result, err
}

// UpdatePublicNetwork - update Publiclink
//
// PARAMS:
//   - instanceId: the specific instance ID
//   - UpdatePublicNetworkArgs: parameters required to update publiclink info
//
// RETURNS:
//   - error: nil if success otherwise the specific error
func (c *Client) UpdatePublicNetwork(instanceID string, args *UpdatePublicNetworkArgs) error {

	err := bce.NewRequestBuilder(c).
		WithMethod(http.PUT).
		WithURL(getPublicNetworkResponseURI(instanceID)).
		WithBody(args).
		Do()

	return err
}

// DeletePublicNetworkWhitelist - delete Publiclink white list
//
// PARAMS:
//   - instanceId: the specific instance ID
//   - DeletePublicNetworkWhiteListArgs: delete publiclinks list
//
// RETURNS:
//   - error: nil if success otherwise the specific error
func (c *Client) DeletePublicNetworkWhitelist(instanceID string, args *DeletePublicNetworkWhitelistArgs) error {

	err := bce.NewRequestBuilder(c).
		WithMethod(http.DELETE).
		WithURL(getPublicNetworkWhitelistURI(instanceID)).
		WithBody(args).
		Do()
	return err
}

// AddPublicNetworkWhitelist - add Publiclink white list
//
// PARAMS:
//   - instanceId: the specific instance ID
//   - DeletePublicNetworkWhiteListArgs: the arguments to delete publiclinks withlist
//
// RETURNS:
//   - error: nil if success otherwise the specific error
func (c *Client) AddPublicNetworkWhitelist(instanceID string, args *AddPublicNetworkWhitelistArgs) error {

	err := bce.NewRequestBuilder(c).
		WithMethod(http.POST).
		WithURL(getPublicNetworkWhitelistURI(instanceID)).
		WithBody(args).
		Do()

	return err
}

// ResetPassword - reset login password
//
// PARAMS:
//   - instanceId: the specific instance ID
//   - ResetPasswordArgs: the arguments to reset password
//
// RETURNS:
//   - error: nil if success otherwise the specific error
//   - map[string]string: the result of reset password
func (c *Client) ResetPassword(instanceID string, args *ResetPasswordArgs) (map[string]string, error) {
	result := make(map[string]string)

	err := bce.NewRequestBuilder(c).
		WithMethod(http.PUT).
		WithURL(getInstanceCredentialURI(instanceID)).
		WithBody(args).
		WithResult(result).
		Do()

	return result, err
}

// CreateTemporaryToken - create temporary token
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - CreateTemporaryTokenArgs: the arguments to crate temporary token
//
// RETURNS:
//   - error: nil if success otherwise the specific error
func (c *Client) CreateTemporaryToken(instanceID string, args *CreateTemporaryTokenArgs) (*CreateTemporaryTokenResponse, error) {
	result := &CreateTemporaryTokenResponse{}

	err := bce.NewRequestBuilder(c).
		WithMethod(http.POST).
		WithURL(getInstanceCredentialURI(instanceID)).
		WithBody(args).
		WithResult(result).
		Do()

	return result, err
}

// CreateRegistry - create registry
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - CreateRegistryArgs: the arguments to crate registry
//
// RETURNS:
//   - error: nil if success otherwise the specific error
//   - CreateRegistryResponse: the result od create registry
func (c *Client) CreateRegistry(instanceID string, args *CreateRegistryArgs) (*CreateRegistryResponse, error) {
	result := &CreateRegistryResponse{}

	err := bce.NewRequestBuilder(c).
		WithMethod(http.POST).
		WithURL(getInstanceRegistryURI(instanceID)).
		WithBody(args).
		WithResult(result).
		Do()

	return result, err
}

// GetRegistryDetail - get a specific registry detail info
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - registryID: the specific registry ID
//
// RETURNS:
//   - error: nil if success otherwise the specific error
//   - RegistryResponse: the result of create registry
func (c *Client) GetRegistryDetail(instanceID, registryID string) (*RegistryResponse, error) {
	result := &RegistryResponse{}

	err := bce.NewRequestBuilder(c).
		WithMethod(http.GET).
		WithURL(getInstanceRegistryIDURI(instanceID, registryID)).
		WithResult(result).
		Do()

	return result, err
}

// ListRegistries - get a registry list of instance
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - ListRegistriesArgs: parameters required to list registry information
//
// RETURNS:
//   - error: nil if success otherwise the specific error
//   - ListRegistriesResponse: the result of list registry
func (c *Client) ListRegistries(instanceID string, args *ListRegistriesArgs) (*ListRegistriesResponse, error) {
	result := &ListRegistriesResponse{}

	err := bce.NewRequestBuilder(c).
		WithMethod(http.GET).
		WithQueryParamFilter("registryName", args.RegistryName).
		WithQueryParamFilter("registryType", args.RegistryType).
		WithQueryParamFilter("pageNo", strconv.Itoa(args.PageNo)).
		WithQueryParamFilter("pageSize", strconv.Itoa(args.PageSize)).
		WithURL(getInstanceRegistryURI(instanceID)).
		WithResult(result).
		Do()

	return result, err
}

// CheckHealthRegistry - check if the registry is healthy
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - RegistryRequestArgs: parameters required to check registry
//
// RETURNS:
//   - error: nil if success otherwise the specific error
func (c *Client) CheckHealthRegistry(instanceID string, args *RegistryRequestArgs) error {

	err := bce.NewRequestBuilder(c).
		WithMethod(http.POST).
		WithURL(getCheckHealthRegistryURI(instanceID)).
		WithBody(args).
		Do()

	return err
}

// UpdateRegistry - update the registry info
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - registryID: the specific registry ID
//   - RegistryRequestArgs: parameters required to update registry
//
// RETURNS:
//   - error: nil if success otherwise the specific error
//   - RegistryResponse: the result of update registry
func (c *Client) UpdateRegistry(instanceID, registryID string, args *RegistryRequestArgs) (*RegistryResponse, error) {
	result := &RegistryResponse{}

	err := bce.NewRequestBuilder(c).
		WithMethod(http.PUT).
		WithURL(getInstanceRegistryIDURI(instanceID, registryID)).
		WithBody(args).
		WithResult(result).
		Do()

	return result, err
}

func (c *Client) DeleteRegistry(instanceID, registryID string) error {

	err := bce.NewRequestBuilder(c).
		WithMethod(http.DELETE).
		WithURL(getInstanceRegistryIDURI(instanceID, registryID)).
		Do()

	return err
}

// ListProjects - list namespaces (projects) of instance
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - ListProjectsArgs: parameters required to list project information
//
// RETURNS:
//   - error: nil if success otherwise the specific error
//   - ListProjectsResponse: the result of list project
func (c *Client) ListProjects(instanceID string, args *ListProjectsArgs) (*ListProjectsResponse, error) {
	result := &ListProjectsResponse{}

	err := bce.NewRequestBuilder(c).
		WithMethod(http.GET).
		WithQueryParamFilter("projectName", args.ProjectName).
		WithQueryParamFilter("pageNo", strconv.Itoa(args.PageNo)).
		WithQueryParamFilter("pageSize", strconv.Itoa(args.PageSize)).
		WithURL(getProjectURI(instanceID)).
		WithResult(result).
		Do()

	return result, err
}

// CreateProject - create namespace (project) of instance
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - CreateProjectArgs: parameters required to create project
//
// RETURNS:
//   - error: nil if success otherwise the specific error
//   - ProjectResponse: the result of create project
func (c *Client) CreateProject(instanceID string, args *CreateProjectArgs) (*ProjectResponse, error) {
	result := &ProjectResponse{}

	err := bce.NewRequestBuilder(c).
		WithMethod(http.POST).
		WithURL(getProjectURI(instanceID)).
		WithBody(args).
		WithResult(result).
		Do()

	return result, err
}

// GetProjectDetail - get a specific namespace (project) detail info
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - projectName: the specific project name
//
// RETURNS:
//   - error: nil if success otherwise the specific error
//   - ProjectResponse: the result of get project detail
func (c *Client) GetProjectDetail(instanceID, projectName string) (*ProjectResponse, error) {
	result := &ProjectResponse{}

	err := bce.NewRequestBuilder(c).
		WithMethod(http.GET).
		WithURL(getProjectNameURI(instanceID, projectName)).
		WithResult(result).
		Do()

	return result, err
}

// DeleteProject - delete a specific namespace (project)
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - projectName: the specific project name
//
// RETURNS:
//   - error: nil if success otherwise the specific error
func (c *Client) DeleteProject(instanceID, projectName string) error {
	err := bce.NewRequestBuilder(c).
		WithMethod(http.DELETE).
		WithURL(getProjectNameURI(instanceID, projectName)).
		Do()

	return err
}

// BatchDeleteProjects - batch delete namespaces (projects)
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - BatchDeleteProjectsArgs: parameters required to batch delete projects
//
// RETURNS:
//   - error: nil if success otherwise the specific error
func (c *Client) BatchDeleteProjects(instanceID string, args *BatchDeleteProjectsArgs) error {
	err := bce.NewRequestBuilder(c).
		WithMethod(http.DELETE).
		WithURL(getProjectURI(instanceID)).
		WithBody(args).
		Do()

	return err
}

// ListRepositories - list repositories of namespace (project)
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - projectName: the specific project name
//   - ListRepositoriesArgs: parameters required to list repository information
//
// RETURNS:
//   - error: nil if success otherwise the specific error
//   - ListRepositoriesResponse: the result of list repository
func (c *Client) ListRepositories(instanceID, projectName string, args *ListRepositoriesArgs) (*ListRepositoriesResponse, error) {
	result := &ListRepositoriesResponse{}

	err := bce.NewRequestBuilder(c).
		WithMethod(http.GET).
		WithQueryParamFilter("repositoryName", args.RepositoryName).
		WithQueryParamFilter("pageNo", strconv.Itoa(args.PageNo)).
		WithQueryParamFilter("pageSize", strconv.Itoa(args.PageSize)).
		WithURL(getRepositoriesURI(instanceID, projectName)).
		WithResult(result).
		Do()

	return result, err
}

// GetRepositoryDetail - get a specific repository detail info
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - projectName: the specific project name
//   - repositoryName: the specific repository name
//
// RETURNS:
//   - error: nil if success otherwise the specific error
//   - RepositoryResponse: the result of get repository detail
func (c *Client) GetRepositoryDetail(instanceID, projectName, repositoryName string) (*RepositoryResponse, error) {
	result := &RepositoryResponse{}
	encodedRepositoryName := base64.RawURLEncoding.EncodeToString([]byte(repositoryName))

	err := bce.NewRequestBuilder(c).
		WithMethod(http.GET).
		WithURL(getRepositoryURI(instanceID, projectName, encodedRepositoryName)).
		WithResult(result).
		Do()

	return result, err
}

// UpdateRepository - update a specific repository info
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - projectName: the specific project name
//   - repositoryName: the specific repository name
//   - UpdateRepositoryArgs: parameters required to update repository info
//
// RETURNS:
//   - error: nil if success otherwise the specific error
//   - RepositoryResponse: the result of update repository
func (c *Client) UpdateRepository(instanceID, projectName, repositoryName string, args *UpdateRepositoryArgs) (*RepositoryResponse, error) {
	result := &RepositoryResponse{}
	encodedRepositoryName := base64.RawURLEncoding.EncodeToString([]byte(repositoryName))

	err := bce.NewRequestBuilder(c).
		WithMethod(http.PUT).
		WithURL(getRepositoryURI(instanceID, projectName, encodedRepositoryName)).
		WithBody(args).
		WithResult(result).
		Do()

	return result, err
}

// DeleteRepository - delete a specific repository
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - projectName: the specific project name
//   - repositoryName: the specific repository name
//
// RETURNS:
//   - error: nil if success otherwise the specific error
func (c *Client) DeleteRepository(instanceID, projectName, repositoryName string) error {
	encodedRepositoryName := base64.RawURLEncoding.EncodeToString([]byte(repositoryName))

	err := bce.NewRequestBuilder(c).
		WithMethod(http.DELETE).
		WithURL(getRepositoryURI(instanceID, projectName, encodedRepositoryName)).
		Do()

	return err
}

// BatchDeleteRepositories - batch delete repositories
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - projectName: the specific project name
//   - BatchDeleteRepositoriesArgs: parameters required to batch delete repositories
//
// RETURNS:
//   - error: nil if success otherwise the specific error
func (c *Client) BatchDeleteRepositories(instanceID, projectName string, args *BatchDeleteRepositoriesArgs) error {
	err := bce.NewRequestBuilder(c).
		WithMethod(http.DELETE).
		WithURL(getRepositoriesURI(instanceID, projectName)).
		WithBody(args).
		Do()

	return err
}

// ListTags - list tags of a specific repository
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - projectName: the specific project name
//   - repositoryName: the specific repository name
//   - ListTagsArgs: parameters required to list tag information
//
// RETURNS:
//   - error: nil if success otherwise the specific error
//   - ListTagsResponse: the result of list tag
func (c *Client) ListTags(instanceID, projectName, repositoryName string, args *ListTagsArgs) (*ListTagsResponse, error) {
	result := &ListTagsResponse{}
	encodedRepositoryName := base64.RawURLEncoding.EncodeToString([]byte(repositoryName))

	err := bce.NewRequestBuilder(c).
		WithMethod(http.GET).
		WithQueryParamFilter("tagName", args.TagName).
		WithQueryParamFilter("pageNo", strconv.Itoa(args.PageNo)).
		WithQueryParamFilter("pageSize", strconv.Itoa(args.PageSize)).
		WithURL(getTagsURI(instanceID, projectName, encodedRepositoryName)).
		WithResult(result).
		Do()

	return result, err
}

// GetTagDetail - get a specific tag detail info
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - projectName: the specific project name
//   - repositoryName: the specific repository name
//   - tagName: the specific tag name
//
// RETURNS:
//   - error: nil if success otherwise the specific error
//   - ImageTag: the result of get tag detail
func (c *Client) GetTagDetail(instanceID, projectName, repositoryName, tagName string) (*ImageTag, error) {
	result := &ImageTag{}
	encodedRepositoryName := base64.RawURLEncoding.EncodeToString([]byte(repositoryName))

	err := bce.NewRequestBuilder(c).
		WithMethod(http.GET).
		WithURL(getTagURI(instanceID, projectName, encodedRepositoryName, tagName)).
		WithResult(result).
		Do()

	return result, err
}

// DeleteTag - delete a specific tag
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - projectName: the specific project name
//   - repositoryName: the specific repository name
//   - tagName: the specific tag name
//
// RETURNS:
//   - error: nil if success otherwise the specific error
func (c *Client) DeleteTag(instanceID, projectName, repositoryName, tagName string) error {
	encodedRepositoryName := base64.RawURLEncoding.EncodeToString([]byte(repositoryName))

	err := bce.NewRequestBuilder(c).
		WithMethod(http.DELETE).
		WithURL(getTagURI(instanceID, projectName, encodedRepositoryName, tagName)).
		Do()

	return err
}

// BatchDeleteTags - batch delete tags
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - projectName: the specific project name
//   - repositoryName: the specific repository name
//   - BatchDeleteTagsArgs: parameters required to batch delete tags
//
// RETURNS:
//   - error: nil if success otherwise the specific error
func (c *Client) BatchDeleteTags(instanceID, projectName, repositoryName string, args *BatchDeleteTagsArgs) error {
	encodedRepositoryName := base64.RawURLEncoding.EncodeToString([]byte(repositoryName))

	err := bce.NewRequestBuilder(c).
		WithMethod(http.DELETE).
		WithURL(getTagsURI(instanceID, projectName, encodedRepositoryName)).
		WithBody(args).
		Do()

	return err
}

// ListRobots - list robot accounts of instance
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - ListRobotsArgs: parameters required to list robot information
//
// RETURNS:
//   - error: nil if success otherwise the specific error
//   - ListRobotsResponse: the result of list robot
func (c *Client) ListRobots(instanceID string, args *ListRobotsArgs) (*ListRobotsResponse, error) {
	result := &ListRobotsResponse{}

	err := bce.NewRequestBuilder(c).
		WithMethod(http.GET).
		WithQueryParamFilter("status", args.Status).
		WithQueryParamFilter("pageNo", strconv.Itoa(args.PageNo)).
		WithQueryParamFilter("pageSize", strconv.Itoa(args.PageSize)).
		WithURL(getRobotListURI(instanceID)).
		WithResult(result).
		Do()

	return result, err
}

// CreateRobot - create robot account of instance
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - CreateRobotArgs: parameters required to create robot
//
// RETURNS:
//   - error: nil if success otherwise the specific error
//   - RobotResponse: the result of create robot
func (c *Client) CreateRobot(instanceID string, args *CreateRobotArgs) (*RobotResponse, error) {
	result := &RobotResponse{}

	err := bce.NewRequestBuilder(c).
		WithMethod(http.POST).
		WithURL(getRobotListURI(instanceID)).
		WithBody(args).
		WithResult(result).
		Do()

	return result, err
}

// UpdateRobot - update a specific robot account
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - robotID: the specific robot ID
//   - UpdateRobotArgs: parameters required to update robot
//
// RETURNS:
//   - error: nil if success otherwise the specific error
func (c *Client) UpdateRobot(instanceID, robotID string, args *UpdateRobotArgs) error {
	err := bce.NewRequestBuilder(c).
		WithMethod(http.PUT).
		WithURL(getRobotURI(instanceID, robotID)).
		WithBody(args).
		Do()

	return err
}

// DeleteRobot - delete a specific robot account
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - robotID: the specific robot ID
//
// RETURNS:
//   - error: nil if success otherwise the specific error
func (c *Client) DeleteRobot(instanceID, robotID string) error {
	err := bce.NewRequestBuilder(c).
		WithMethod(http.DELETE).
		WithURL(getRobotURI(instanceID, robotID)).
		Do()

	return err
}

// RefreshRobotSecret - refresh robot secret token
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - robotID: the specific robot ID
//   - RefreshRobotSecretArgs: optional parameters to set secret
//
// RETURNS:
//   - error: nil if success otherwise the specific error
//   - RobotTokenResponse: the result of refresh robot token
func (c *Client) RefreshRobotSecret(instanceID, robotID string, args *RefreshRobotSecretArgs) (*RobotTokenResponse, error) {
	result := &RobotTokenResponse{}

	err := bce.NewRequestBuilder(c).
		WithMethod(http.PUT).
		WithURL(getRobotSecretURI(instanceID, robotID)).
		WithBody(args).
		WithResult(result).
		Do()

	return result, err
}

// ListBuildRepositoryTask - list the build task info
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - projectName: the specific project Name
//   - repositoryName: the specific registry Name
//   - ListBuildRepositoryTaskArgs: parameters required to get task list
//
// RETURNS:
//   - error: nil if success otherwise the specific error
//   - ListBuildRepositoryTaskResponse: the result of build task list

func (c *Client) ListBuildRepositoryTask(instanceID, projectName, repositoryName string, args *ListBuildRepositoryTaskArgs) (
	*ListBuildRepositoryTaskResponse, error) {
	result := &ListBuildRepositoryTaskResponse{}

	err := bce.NewRequestBuilder(c).
		WithMethod(http.GET).
		WithQueryParamFilter("keywordType", args.KeywordType).
		WithQueryParamFilter("keyword", args.Keyword).
		WithQueryParamFilter("pageNo", strconv.Itoa(args.PageNo)).
		WithQueryParamFilter("pageSize", strconv.Itoa(args.PageSize)).
		WithURL(getImageBuildURI(instanceID, projectName, base64.RawURLEncoding.EncodeToString([]byte(repositoryName)))).
		WithResult(result).
		Do()

	return result, err
}

// CreateBuildRepositoryTask - create the build task
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - projectName: the specific project Name
//   - repositoryName: the specific registry Name
//	 - BuildRepositoryTaskArgs: parameters required to create build task
//
// RETURNS:
//   - error: nil if success otherwise the specific error
//   - BuildRepositoryTaskResponse: the result of build task

func (c *Client) CreateBuildRepositoryTask(instanceID, projectName, repositoryName string, args *BuildRepositoryTaskArgs) (
	*BuildRepositoryTaskResponse, error) {
	result := &BuildRepositoryTaskResponse{}

	err := bce.NewRequestBuilder(c).
		WithMethod(http.POST).
		WithURL(getImageBuildURI(instanceID, projectName, base64.RawURLEncoding.EncodeToString([]byte(repositoryName)))).
		WithBody(args).
		WithResult(result).
		Do()

	return result, err
}

// GetBuildRepositoryTask - get the build task
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - projectName: the specific project Name
//   - repositoryName: the specific registry Name
//	 - imageBuildID: the specific image build ID
//
// RETURNS:
//   - error: nil if success otherwise the specific error
//   - BuildRepositoryTaskResult: the result of build task

func (c *Client) GetBuildRepositoryTask(instanceID, projectName, repositoryName, imageBuildID string) (*BuildRepositoryTaskResult, error) {
	result := &BuildRepositoryTaskResult{}

	err := bce.NewRequestBuilder(c).
		WithMethod(http.GET).
		WithURL(getImageBuildInfoURI(instanceID, projectName, base64.RawURLEncoding.EncodeToString([]byte(repositoryName)), imageBuildID)).
		WithResult(result).
		Do()

	return result, err
}

// DeleteBuildRepositoryTask - batch delete the build task
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - projectName: the specific project Name
//   - repositoryName: the specific registry Name
//
// RETURNS:
//   - error: nil if success otherwise the specific error

func (c *Client) DeleteBuildRepositoryTask(instanceID, projectName, repositoryName, imageBuildID string) error {

	err := bce.NewRequestBuilder(c).
		WithMethod(http.DELETE).
		WithURL(getImageBuildInfoURI(instanceID, projectName, base64.RawURLEncoding.EncodeToString([]byte(repositoryName)), imageBuildID)).
		Do()

	return err
}

// BatchDeleteBuildRepositoryTask - batch delete the build task
//
// PARAMS:
//   - instanceID: the specific instance ID
//   - projectName: the specific project Name
//   - repositoryName: the specific registry Name
//   - BatchDeleteBuildRepositoryTaskArgs: parameters required to batch delete build task
//
// RETURNS:
//   - error: nil if success otherwise the specific error

func (c *Client) BatchDeleteBuildRepositoryTask(instanceID, projectName, repositoryName string, args *BatchDeleteBuildRepositoryTaskArgs) error {

	err := bce.NewRequestBuilder(c).
		WithMethod(http.DELETE).
		WithBody(args).
		WithURL(getImageBuildURI(instanceID, projectName, base64.RawURLEncoding.EncodeToString([]byte(repositoryName)))).
		Do()

	return err
}

// AssignInstanceTag - assign instance tag
//
// PARAMS:
//   - instanceId: the specific instance ID
//   - AssignTagsRequest: parameters required to assign instance tag info
//
// RETURNS:
//   - error: nil if success otherwise the specific error
func (c *Client) AssignInstanceTag(instanceID string, args *AssignTagsRequest) error {

	err := bce.NewRequestBuilder(c).
		WithMethod(http.PUT).
		WithURL(getInstanceTagURI(instanceID)).
		WithBody(args).
		Do()

	return err
}
