package commands

import (
	"encoding/json"
	"fmt"

	"github.com/sirupsen/logrus"
	"github.com/urfave/cli/v2"

	"gitlab.com/gitlab-org/release-cli/internal/flags"
	"gitlab.com/gitlab-org/release-cli/internal/gitlab"
)

// Get a release by tag name command
func Get(log logrus.FieldLogger, httpClientFn httpClientFn) *cli.Command {
	return &cli.Command{
		Name:  "get",
		Usage: "Get a Release by tag name using GitLab's Releases API https://docs.gitlab.com/ee/api/releases/index.html#get-a-release-by-a-tag-name",
		Action: func(ctx *cli.Context) error {
			client, err := httpClientFn(ctx, log)
			if err != nil {
				return fmt.Errorf("http client: %w", err)
			}

			return getRelease(ctx, log, client)
		},
		Subcommands: nil,
		Flags: []cli.Flag{
			&cli.StringFlag{
				Name:     flags.TagName,
				Usage:    "The Git tag the release is associated with",
				Required: true,
				EnvVars:  []string{"CI_COMMIT_TAG"},
			},
			&cli.BoolFlag{
				Name:     flags.IncludeHTMLDescription,
				Usage:    "If true, a response includes HTML rendered Markdown of the release description",
				Required: false,
				EnvVars:  []string{"INCLUDE_HTML_DESCRIPTION"},
			},
		},
	}
}

func getRelease(ctx *cli.Context, log logrus.FieldLogger, httpClient gitlab.HTTPClient) error {
	projectID := ctx.String(flags.ProjectID)
	serverURL := ctx.String(flags.ServerURL)
	jobToken := ctx.String(flags.JobToken)
	privateToken := ctx.String(flags.PrivateToken)
	tagName := ctx.String(flags.TagName)
	includeHTML := ctx.Bool(flags.IncludeHTMLDescription)

	l := log.WithFields(logrus.Fields{
		"command":                    ctx.Command.Name,
		flags.ServerURL:              serverURL,
		flags.ProjectID:              projectID,
		flags.TagName:                tagName,
		flags.IncludeHTMLDescription: includeHTML,
	})

	l.Info("Getting release")

	gitlabClient, err := gitlab.New(serverURL, jobToken, privateToken, projectID, httpClient, log)
	if err != nil {
		return fmt.Errorf("create GitLab client: %w", err)
	}

	release, err := gitlabClient.GetRelease(ctx.Context, tagName, includeHTML)
	if err != nil {
		return fmt.Errorf("get release: %w", err)
	}

	if err := json.NewEncoder(ctx.App.Writer).Encode(release); err != nil {
		return fmt.Errorf("encode release response: %w", err)
	}

	return nil
}
