package handler

import (
	"fmt"
	"net/http"
	"strconv"

	"github.com/jstemmer/go-junit-report/v2/junit"
	"github.com/labstack/echo/v4"
	"github.com/pingcap/test-infra/common/model"
	"github.com/pingcap/test-infra/services/tcms/service"
	serror "github.com/pingcap/test-infra/services/tcms/service/common/errors"
	"github.com/pingcap/test-infra/services/tcms/utils"
)

type ReportHandler struct {
	s service.ReportService
}

func (h *ReportHandler) GetPlanReport(c echo.Context) error {
	id, err := strconv.Atoi(c.Param("id"))
	if err != nil {
		return serror.NewMsg(http.StatusBadRequest, "invalid id in path")
	}
	report, err := h.s.GetPlanReport(utils.EmbedIntoContext(c.(utils.Context)), model.ID(id))
	if err != nil {
		return err
	}
	return c.XMLPretty(http.StatusOK, toJUnitXml(*report), "\t")
}

func toJUnitXml(report model.TestReport) junit.Testsuites {
	suits := junit.Testsuites{}
	for _, suit := range report.Suits {
		s := junit.Testsuite{Name: suit.Name, Tests: len(suit.Cases)}
		for _, caseReport := range suit.Cases {
			s.Testcases = append(s.Testcases, caseReportToJUnitCase(caseReport))
		}
		suits.Suites = append(suits.Suites, s)
	}
	return suits
}

func caseReportToJUnitCase(r model.CaseReport) junit.Testcase {
	rt := junit.Testcase{Name: r.Name, Time: fmt.Sprintf("%s", r.Time)}
	if r.Failure != nil {
		rt.Failure = &junit.Result{Message: r.Failure.Message, Data: r.Failure.Text}
	}
	if r.Skipped != nil {
		rt.Skipped = &junit.Result{Message: r.Skipped.Message, Data: r.Skipped.Text}
	}
	return rt
}
