// 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"
	"fmt"
	"strings"

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

func cmdCreateCL(authOpts auth.Options) *subcommands.Command {
	return &subcommands.Command{
		UsageLine: "create-cl -host <gerrit-host> -project <gerrit-project> -subject <cl-subject> -file-edit <filepath1>:<contents1>, ...",
		ShortDesc: "Create a CL with file edits.",
		LongDesc:  "Create a CL with file edits.",
		CommandRun: func() subcommands.CommandRun {
			c := &createCLRun{}
			c.Init(authOpts)
			return c
		},
	}
}

type createCLRun struct {
	commonFlags
	edits   fileEdits
	subject string
}

func (c *createCLRun) Init(defaultAuthOpts auth.Options) {
	c.commonFlags.Init(defaultAuthOpts)
	c.Flags.StringVar(&c.subject, "subject", "", "CL subject.")
	c.Flags.Var(&c.edits, "file-edit", "filepath:content pairs. Repeatable.")
}

func (c *createCLRun) Parse(a subcommands.Application, args []string) error {
	if err := c.commonFlags.Parse(); err != nil {
		return err
	}
	if c.subject == "" {
		return fmt.Errorf("-subject is required")
	}
	if len(c.edits) == 0 {
		return fmt.Errorf("at least one -file-edit is required")
	}
	return nil
}

// fileEdit represents a file to edit in a repository.
type fileEdit struct {
	filepath string
	contents string
}

// String returns a string representation of the file edit.
func (e *fileEdit) String() string {
	return fmt.Sprintf("%s:%s", e.filepath, e.contents)
}

// newFileEdit returns a fileEdit for a filepath:contents string.
func newFileEdit(editStr string) (*fileEdit, error) {
	sp := strings.Split(editStr, ":")
	if len(sp) != 2 {
		return nil, fmt.Errorf("%q is not of format filepath:contents", editStr)
	}
	return &fileEdit{filepath: sp[0], contents: sp[1]}, nil
}

// fileEdits is a flag.Getter implementation representing a []*fileEdit.
type fileEdits []*fileEdit

// String returns a comma-separated string representation of the flag file edits.
func (f fileEdits) String() string {
	strs := make([]string, len(f))
	for i, edit := range f {
		strs[i] = edit.String()
	}
	return strings.Join(strs, ", ")
}

// Set records seeing a flag value.
func (f *fileEdits) Set(val string) error {
	fe, err := newFileEdit(val)
	if err != nil {
		return err
	}
	*f = append(*f, fe)
	return nil
}

// Get retrieves the flag value.
func (f fileEdits) Get() interface{} {
	return []*fileEdit(f)
}

func (c *createCLRun) main(a subcommands.Application) error {
	ctx := context.Background()
	gitilesClient, err := newGitilesClient(ctx, strings.Replace(c.gerritHost, "-review", "", 1), c.gerritProject, c.parsedAuthOpts)
	if err != nil {
		return err
	}
	gerritClient, err := newGerritClient(ctx, c.gerritHost, c.gerritProject, c.parsedAuthOpts)
	if err != nil {
		return err
	}
	// Create the change at refs/heads/master HEAD.
	commit, err := gitilesClient.getLatestCommit(ctx)
	if err != nil {
		return err
	}
	changeInfo, err := gerritClient.createChange(ctx, c.subject, commit)
	if err != nil {
		return err
	}
	for _, edit := range c.edits {
		if err := gerritClient.editFile(ctx, changeInfo.Number, edit.filepath, edit.contents); err != nil {
			return err
		}
	}
	if err := gerritClient.publishEdits(ctx, changeInfo.Number); err != nil {
		return err
	}
	fmt.Printf("%d\n", changeInfo.Number)
	return nil
}

func (c *createCLRun) 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
}
