// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"context"
	"encoding/json"
	"flag"
	"log"

	"cos.googlesource.com/cos/tools.git/src/pkg/config"
	"cos.googlesource.com/cos/tools.git/src/pkg/fs"
	"cos.googlesource.com/cos/tools.git/src/pkg/provisioner"
	"github.com/google/subcommands"
)

const (
	anthosInstallerVersion       = "anthos_installer-linux-amd64-v0.0.1-ecea8c6.tar.gz"
	anthosInstallerReleaseBucket = "cos-anthos-builds-us"
)

// InstallPackage installs the packages based on thes
// pkg-spec by the anthos-installer.
type InstallPackage struct {
	PkgSpecURL string
	TopWorkDir string
}

// Name implements subcommands.Command.Name.
func (ip *InstallPackage) Name() string {
	return "anthos-installer-install"
}

// Synopsis implements subcommands.Command.Synopsis.
func (ip *InstallPackage) Synopsis() string {
	return "Installs packages specified by pkgspec files."
}

// Usage implements subcommands.Command.Usage.
func (ip *InstallPackage) Usage() string {
	return `anthos-installer-install [flags]
`
}

// SetFlags implements subcommands.Command.SetFlags.
func (ip *InstallPackage) SetFlags(f *flag.FlagSet) {
	f.StringVar(&ip.PkgSpecURL, "pkgspec-url", "", "URL path that points to the package spec.")
	f.StringVar(&ip.TopWorkDir, "top-workdir", "", "Path to the top working directory, used to hold package spec and package tarballs.")
}

// Execute implements subcommands.Command.Execute. It configures the current image build process to
// customize the result image with a shell script.
func (ip *InstallPackage) Execute(ctx context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus {
	if f.NArg() != 0 {
		f.Usage()
		return subcommands.ExitUsageError
	}
	files, ok := args[0].(*fs.Files)
	if !ok {
		log.Panic("InstallPackage expects *fs.Files")
	}

	if ip.PkgSpecURL == "" {
		log.Printf("Required package spec is not provided for %s step\n", ip.Name())
		return subcommands.ExitFailure
	}

	var provConfig provisioner.Config
	if err := config.LoadFromFile(files.ProvConfig, &provConfig); err != nil {
		log.Println(err)
		return subcommands.ExitFailure
	}

	buf, err := json.Marshal(&provisioner.InstallPackagesStep{
		BuildContext:                 "user",
		PkgSpecURL:                   ip.PkgSpecURL,
		TopWorkDir:                   ip.TopWorkDir,
		AnthosInstallerReleaseBucket: anthosInstallerReleaseBucket,
		AnthosInstallerVersion:       anthosInstallerVersion,
	})

	if err != nil {
		log.Println(err)
		return subcommands.ExitFailure
	}

	provConfig.Steps = append(provConfig.Steps, provisioner.StepConfig{
		Type: "InstallPackages",
		Args: json.RawMessage(buf),
	})

	if err := config.SaveConfigToPath(files.ProvConfig, &provConfig); err != nil {
		log.Println(err)
		return subcommands.ExitFailure
	}
	return subcommands.ExitSuccess
}
