package store

import (
	"testing"

	"github.com/stretchr/testify/assert"

	"github.com/pingcap/test-infra/common/model"
	"github.com/pingcap/test-infra/common/model/tcms/request"
	"github.com/pingcap/test-infra/services/tcms/utils"
)

func TestUpdateTriage(t *testing.T) {
	s := setup(t)
	defer s.Shutdown()
	triageSvc := s.Triage
	ctx := utils.FakeCtx()

	triagePhase := model.TriagePhaseTriaging
	if assert.NoError(t, triageSvc.UpdatePlanTriage(ctx, 2, &request.PlanTriageUpdateRequest{
		TriagePhase: &triagePhase,
	})) {
		solution := model.ExecFailSolutionFIX
		if assert.NoError(t, triageSvc.UpdatePlanTriage(ctx, 2, &request.PlanTriageUpdateRequest{
			Solution: &solution,
		})) {
			triage, err := triageSvc.GetPlanTriage(ctx, 2)
			assert.NoError(t, err)
			assert.Equal(t, triagePhase, triage.TriagePhase)
		}
	}
}

func TestCreateCaseTriage(t *testing.T) {
	s := setup(t)
	defer s.Shutdown()
	triageSvc := s.Triage
	ctx := utils.FakeCtx()

	triagePhase := model.TriagePhaseTriaging
	if assert.NoError(t, triageSvc.UpdatePlanTriage(ctx, 2, &request.PlanTriageUpdateRequest{
		TriagePhase: &triagePhase,
	})) {
		res, err := triageSvc.CreateCaseTriage(ctx, &model.CaseTriage{
			PlanExecutionID: model.ID(2),
			CaseExecutionID: model.ID(6),
			Reason:          model.CaseExecFailReasonEnv,
			Solution:        model.ExecFailSolutionPAUSE,
			IssueLink:       "link",
			Note:            "note",
		})
		if assert.NoError(t, err) {
			assert.Equal(t, model.CaseExecFailReasonEnv, res.Reason)
			assert.Equal(t, model.ExecFailSolutionPAUSE, res.Solution)
		}
	}
}

func TestForkCaseTriage(t *testing.T) {
	s := setup(t)
	defer s.Shutdown()
	triageSvc := s.Triage
	ctx := utils.FakeCtx()

	triagePhase := model.TriagePhaseTriaging
	if assert.NoError(t, triageSvc.UpdatePlanTriage(ctx, 2, &request.PlanTriageUpdateRequest{
		TriagePhase: &triagePhase,
	})) {
		// create caseTriage for caseExec 6
		res, err := triageSvc.CreateCaseTriage(ctx, &model.CaseTriage{
			PlanExecutionID: model.ID(2),
			CaseExecutionID: model.ID(6),
			Reason:          model.CaseExecFailReasonEnv,
			Solution:        model.ExecFailSolutionPAUSE,
			IssueLink:       "link",
			Note:            "note",
		})
		if assert.NoError(t, err) {
			assert.Equal(t, model.CaseExecFailReasonEnv, res.Reason)
			assert.Equal(t, model.ExecFailSolutionPAUSE, res.Solution)
			assert.Equal(t, "link", res.IssueLink)
			assert.Equal(t, "note", res.Note)
			assert.Equal(t, model.ID(0), res.ForkedFrom)
		}

		// suggest related caseTriage exclude self
		suggestions, err := triageSvc.SuggestCaseTriages(ctx, 6)
		if assert.NoError(t, err) {
			assert.Equal(t, 0, len(suggestions))
		}

		// suggest related caseTriage
		suggestions, err = triageSvc.SuggestCaseTriages(ctx, 7)
		if assert.NoError(t, err) {
			if assert.Equal(t, 1, len(suggestions)) {
				assert.Equal(t, model.ID(6), suggestions[0].CaseExecutionID)
			}
		}

		// create caseTriage 6 for caseExec 7
		forked, err := triageSvc.ForkCaseTriages(ctx, 7, 6)
		if assert.NoError(t, err) {
			assert.Equal(t, model.CaseExecFailReasonEnv, forked.Reason)
			assert.Equal(t, model.ExecFailSolutionPAUSE, forked.Solution)
			assert.Equal(t, "link", forked.IssueLink)
			assert.Equal(t, "note", forked.Note)
			assert.Equal(t, model.ID(6), forked.ForkedFrom)
		}
	}
}
