package taskruns

import (
	"context"
	"strconv"

	"github.com/pingcap/test-infra/common/client/tcms/client"
	"github.com/pingcap/test-infra/common/client/util"
	"github.com/pingcap/test-infra/common/model"
	"github.com/pingcap/test-infra/common/model/tcms/taskruns"
)

type SvcTaskClient interface {
	List(ctx context.Context, opts taskruns.ListSvcTaskOpts) (*taskruns.SvcTaskList, error)
	Get(ctx context.Context, id model.ID, opts taskruns.GetSvcTaskOpts) (*taskruns.SvcTask, error)
	GetByName(ctx context.Context, name string, opts taskruns.GetSvcTaskOpts) (*taskruns.SvcTask, error)
	Create(ctx context.Context, obj taskruns.SvcTask, opts taskruns.CreateSvcTaskOpts) (*taskruns.SvcTask, error)
	Update(ctx context.Context, obj taskruns.SvcTask, opts taskruns.UpdateSvcTaskOpts) (*taskruns.SvcTask, error)
	Delete(ctx context.Context, id model.ID, opts taskruns.DeleteSvcTaskOpts) (*taskruns.SvcTask, error)
}

type svcTaskClient struct {
	tcmsClient client.TcmsClient
}

const svcTaskPath = "api/v1/svctasks"

func (c svcTaskClient) NewRequest(ctx context.Context) *util.Request {
	return c.tcmsClient.NewRequest().AppendPath(svcTaskPath).WithContext(ctx)
}

func (c svcTaskClient) List(ctx context.Context, opts taskruns.ListSvcTaskOpts) (*taskruns.SvcTaskList, error) {
	rt := taskruns.SvcTaskList{}
	_, err := c.NewRequest(ctx).
		Get().
		SchemaQuery(opts).
		Into(&rt).
		Do()
	if err != nil {
		return nil, err
	}
	return &rt, nil
}

func (c svcTaskClient) Get(ctx context.Context, id model.ID, opts taskruns.GetSvcTaskOpts) (*taskruns.SvcTask, error) {
	rt := taskruns.SvcTask{}
	_, err := c.NewRequest(ctx).
		Get().
		AppendPath(strconv.Itoa(int(id))).
		SchemaQuery(opts).
		Into(&rt).
		Do()
	if err != nil {
		return nil, err
	}
	return &rt, nil
}

func (c svcTaskClient) GetByName(ctx context.Context, name string, opts taskruns.GetSvcTaskOpts) (*taskruns.SvcTask, error) {
	rt := taskruns.SvcTask{}
	_, err := c.NewRequest(ctx).
		Get().
		AppendPath("name").
		AppendPath(name).
		SchemaQuery(opts).
		Into(&rt).
		Do()
	if err != nil {
		return nil, err
	}
	return &rt, nil
}

func (c svcTaskClient) Create(ctx context.Context, obj taskruns.SvcTask, opts taskruns.CreateSvcTaskOpts) (*taskruns.SvcTask, error) {
	rt := taskruns.SvcTask{}
	_, err := c.NewRequest(ctx).
		Post().
		Json(obj).
		SchemaQuery(opts).
		Into(&rt).
		Do()
	if err != nil {
		return nil, err
	}
	return &rt, nil
}

func (c svcTaskClient) Delete(ctx context.Context, id model.ID, opts taskruns.DeleteSvcTaskOpts) (*taskruns.SvcTask, error) {
	rt := taskruns.SvcTask{}
	_, err := c.NewRequest(ctx).
		Delete().
		AppendPath(strconv.Itoa(int(id))).
		SchemaQuery(opts).
		Into(&rt).
		Do()
	if err != nil {
		return nil, err
	}
	return &rt, nil
}

func (c svcTaskClient) Update(ctx context.Context, obj taskruns.SvcTask, opts taskruns.UpdateSvcTaskOpts) (*taskruns.SvcTask, error) {
	rt := taskruns.SvcTask{}
	_, err := c.NewRequest(ctx).
		Put().
		AppendPath(strconv.Itoa(int(obj.MetaData.ID))).
		Json(obj).
		SchemaQuery(opts).
		Into(&rt).
		Do()
	if err != nil {
		return nil, err
	}
	return &rt, nil
}

func NewSvcTaskClient(tcmsClient client.TcmsClient) SvcTaskClient {
	return svcTaskClient{tcmsClient: tcmsClient}
}
