package trivy

import (
	"time"

	"github.com/pingcap-inc/security/baseline/pkg/utils"
	"github.com/urfave/cli/v2"
	"golang.org/x/xerrors"
)

// BaseOption holds the base options
type BaseOption struct {
	GITHUB_TOKEN string
	CacheDir     string
	Timeout      time.Duration
}

// NewOption is the factory method for Option
func NewBaseOption(ctx *cli.Context) (*BaseOption, error) {
	return &BaseOption{
		GITHUB_TOKEN: ctx.String("github-token"),
		CacheDir:     ctx.String("cache-dir"),
		Timeout:      ctx.Duration("timeout"),
	}, nil
}

// ImageOption holds the image scanner options
type ImageOption struct {
	*BaseOption

	Severity string
	Targets  []string
}

// NewImageOption is the factory method for ImageOption
func NewImageOption(ctx *cli.Context) (*ImageOption, error) {
	opt, err := NewBaseOption(ctx)
	if err != nil {
		return nil, err
	}

	opt.CacheDir = utils.TrivyCacheDir(opt.CacheDir)

	image_option := &ImageOption{
		BaseOption: opt,
	}

	if args := ctx.Args().Slice(); len(args) > 0 {
		image_option.Severity = ctx.String("severity")
		image_option.Targets = append(image_option.Targets, args...)
		return image_option, nil
	} else {
		return nil, xerrors.Errorf("Please specify at least one target image.")
	}
}

// RepoOption holds the repository scanner options
type RepoOption struct {
	*BaseOption

	Severity string
	Targets  []string
}

// NewRepoOption is the factory method for RepoOption
func NewRepoOption(ctx *cli.Context) (*RepoOption, error) {
	opt, err := NewBaseOption(ctx)
	if err != nil {
		return nil, err
	}

	opt.CacheDir = utils.TrivyCacheDir(opt.CacheDir)

	repo_option := &RepoOption{
		BaseOption: opt,
	}

	if args := ctx.Args().Slice(); len(args) > 0 {
		repo_option.Severity = ctx.String("severity")
		repo_option.Targets = append(repo_option.Targets, args...)
		return repo_option, nil
	} else {
		return nil, xerrors.Errorf("Please specify at least one target repository.")
	}
}
