// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package main

import (
	"context"
	"errors"
	"fmt"

	"github.com/maruel/subcommands"
	"go.chromium.org/luci/auth"
)

func cmdAbandonCL(authOpts auth.Options) *subcommands.Command {
	return &subcommands.Command{
		UsageLine: "abandon-cl -host <gerrit-host> -project <gerrit-project> -change-num <change-num>",
		ShortDesc: "Abandon a CL.",
		LongDesc:  "Abandon a CL.",
		CommandRun: func() subcommands.CommandRun {
			c := &abandonCLRun{}
			c.Init(authOpts)
			return c
		},
	}
}

type abandonCLRun struct {
	commonFlags
	changeNum int64
}

func (c *abandonCLRun) Init(defaultAuthOpts auth.Options) {
	c.commonFlags.Init(defaultAuthOpts)
	c.Flags.Int64Var(&c.changeNum, "change-num", 0, "Gerrit change number.")
}

func (c *abandonCLRun) Parse(a subcommands.Application, args []string) error {
	if err := c.commonFlags.Parse(); err != nil {
		return err
	}
	if c.changeNum == 0 {
		return errors.New("-change-num is required")
	}
	return nil
}

func (c *abandonCLRun) main(a subcommands.Application) error {
	ctx := context.Background()
	gerritClient, err := newGerritClient(ctx, c.gerritHost, c.gerritProject, c.parsedAuthOpts)
	if err != nil {
		return err
	}
	return gerritClient.abandonChange(ctx, c.changeNum)
}

func (c *abandonCLRun) Run(a subcommands.Application, args []string, env subcommands.Env) int {
	if err := c.Parse(a, args); err != nil {
		fmt.Fprintf(a.GetErr(), "%s: %s\n", a.GetName(), err)
		return 1
	}

	if err := c.main(a); err != nil {
		fmt.Fprintf(a.GetErr(), "%s: %s\n", a.GetName(), err)
		return 1
	}
	return 0
}
