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 SvcTaskRunClient interface {
	List(ctx context.Context, opts taskruns.ListSvcTaskRunOpts) (*taskruns.SvcTaskRunList, error)
	Get(ctx context.Context, id model.ID, opts taskruns.GetSvcTaskRunOpts) (*taskruns.SvcTaskRun, error)
	Create(ctx context.Context, obj taskruns.SvcTaskRun, opts taskruns.CreateSvcTaskRunOpts) (*taskruns.SvcTaskRun, error)
	UpdateStatus(ctx context.Context, obj taskruns.SvcTaskRun, opts taskruns.UpdateSvcTaskRunOpts) (*taskruns.SvcTaskRun, error)
	Delete(ctx context.Context, id model.ID, opts taskruns.DeleteSvcTaskRunOpts) (*taskruns.SvcTaskRun, error)
}

type svcTaskRunClient struct {
	tcmsClient client.TcmsClient
}

const svcTaskRunPath = "api/v1/svctaskruns"

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

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

func (c svcTaskRunClient) Get(ctx context.Context, id model.ID, opts taskruns.GetSvcTaskRunOpts) (*taskruns.SvcTaskRun, error) {
	rt := taskruns.SvcTaskRun{}
	_, 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 svcTaskRunClient) Create(ctx context.Context, obj taskruns.SvcTaskRun, opts taskruns.CreateSvcTaskRunOpts) (*taskruns.SvcTaskRun, error) {
	rt := taskruns.SvcTaskRun{}
	_, err := c.NewRequest(ctx).
		Post().
		Json(obj).
		SchemaQuery(opts).
		Into(&rt).
		Do()
	if err != nil {
		return nil, err
	}
	return &rt, nil
}

func (c svcTaskRunClient) Delete(ctx context.Context, id model.ID, opts taskruns.DeleteSvcTaskRunOpts) (*taskruns.SvcTaskRun, error) {
	rt := taskruns.SvcTaskRun{}
	_, 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 svcTaskRunClient) UpdateStatus(ctx context.Context, obj taskruns.SvcTaskRun, opts taskruns.UpdateSvcTaskRunOpts) (*taskruns.SvcTaskRun, error) {
	rt := taskruns.SvcTaskRun{}
	_, err := c.NewRequest(ctx).
		Put().
		AppendPath(strconv.Itoa(int(obj.MetaData.ID))).
		AppendPath("status").
		Json(obj).
		SchemaQuery(opts).
		Into(&rt).
		Do()
	if err != nil {
		return nil, err
	}
	return &rt, nil
}

func NewSvcTaskRunClient(tcmsClient client.TcmsClient) SvcTaskRunClient {
	return svcTaskRunClient{tcmsClient: tcmsClient}
}
