package input

import (
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"cos.googlesource.com/cos/tools.git/src/cmd/cos_image_analyzer/internal/utilities"
)

// BinaryDiffTypes is a list of all valid binary differnce types
var BinaryDiffTypes = []string{"Version", "BuildID", "Rootfs", "Kernel-command-line", "Stateful-partition", "Partition-structure", "Sysctl-settings", "OS-config", "Kernel-configs"}

// Default Rootfs entires that are overridden by the "compress-rootfs" flag
var defaultCompressRootfs = []string{"/bin/", "/lib/modules/", "/lib64/", "/usr/libexec/", "/usr/bin/", "/usr/sbin/", "/usr/lib64/", "/usr/share/zoneinfo/", "/usr/share/git/", "/usr/lib/", "/sbin/", "/etc/ssh/", "/etc/os-release/", "/etc/package_list/"}

// Default Stateful entires that are overridden by the "compress-stateful" flag
var defaultCompressStateful = []string{"/var_overlay/db/"}

// Custom usage function. See -h flag
func printUsage() {
	usageTemplate := `NAME
	cos_image_analyzer - finds all meaningful differences of two COS Images (binary and package differences).
		If only one image is passed in, its binary info and package info will be returned.

SYNOPSIS
	%s [-local] FILE-1 [FILE-2] (default true)
		FILE - the local file path to the DOS/MBR boot sector file of your image (Ex: disk.raw)
		Ex: %s image-cos-77-12371-273-0/disk.raw image-cos-81-12871-119-0/disk.raw

	%s -local -binary=Sysctl-settings,OS-config -package=false image-cos-77-12371-273-0/disk.raw

	%s -gcs GCS-PATH-1 [GCS-PATH-2]
		GCS-PATH - the GCS "gs://bucket/object" path for the COS Image ("object" is type .tar.gz)
		Ex: %s -gcs gs://my-bucket/cos-images/cos-77-12371-273-0.tar.gz gs://my-bucket/cos-images/cos-81-12871-119-0.tar.gz


DESCRIPTION
	Input Flags:
	-local (default true, flag is optional)
		input is one or two DOS/MBR disk file on the local filesystem. If the images are downloaded from
		Google Cloud as a tarball, decompress the tarball first then pass the disk.raw file to the program.
	-gcs
		input is one or two objects stored on Google Cloud Storage of type (.tar.gz). This flag temporarily downloads,
		unzips, and loop device mounts the images into this tool's directory.
		To download images from Google Cloud Storage, you need to pass a service account credential to the program.
		Folllow https://cloud.google.com/docs/authentication/production#create_service_account to create a service account and
		download the service account key. Then point environment variable GOOGLE_APPLICATION_CREDENTIALS to the key file then
		run the program.

	Difference Flags:
	-binary (string)
		specify which type of binary difference to show. Types "Version", "BuildID", "Kernel-command-line",
		"Partition-structure", "Sysctl-settings", and "Kernel-configs" are supported for one and two image. "Rootfs",
		"Stateful-partition", and "OS-config" are only supported for two images. To list multiple types separate by
		comma. To NOT list any binary difference, set flag to "false". (default all types)
	-package
		specify whether to show package difference. Shows addition/removal of packages and package version updates.
		To NOT list any package difference, set flag to false. (default false)

	Attribute Flags
	-verbose
		include flag to increase verbosity of Rootfs, Stateful-partition, and OS-config differences. See -compress-rootfs and
		-compress-stateful flags descriptions for the directories that are compressed by default.
	-compress-rootfs (string)
		to customize which directories are compressed in a non-verbose Rootfs and OS-config difference output, provide a local
		file path to a .txt file. Format of the file must be one root file path per line with an ending back slash and no commas.
		By default the directory(s) that are compressed during a diff are /bin/, /lib/modules/, /lib64/, /usr/libexec/, /usr/bin/,
		/usr/sbin/, /usr/lib64/, /usr/share/zoneinfo/, /usr/share/git/, /usr/lib/, /sbin/, /etc/ssh/, /etc/os-release/ and
		/etc/package_list/.
	-compress-stateful (string)
		to customize which directories are compressed in a non-verbose Stateful-partition difference output, provide a local
		file path to a .txt file. Format of file must be one root file path per line with no commas. By default the directory(s)
		that are compressed during a diff are /var_overlay/db/.

	Output Flags:
	-output (string)
		Specify format of output. Only "terminal" stdout or "json" object is supported. (default "terminal")

OUTPUT
	Based on the "-output" flag. Either "terminal" stdout or machine readable "json" format.

NOTE
	The root permission is needed for this program because it needs to mount images into your local filesystem to calculate difference.
`
	cmd := filepath.Base(os.Args[0])
	usage := fmt.Sprintf(usageTemplate, cmd, cmd, cmd, cmd, cmd)
	fmt.Printf("%s", usage)
}

// FlagErrorChecking validates command-line flags stored in the FlagInfo struct
// Input:
//   (*FlagInfo) flagInfo - A struct that stores all flag input
// Output: nil on success, else error
func FlagErrorChecking(flagInfo *FlagInfo) error {
	// Error Checking
	if (flagInfo.LocalPtr && flagInfo.GcsPtr) || (flagInfo.LocalPtr && flagInfo.CosCloudPtr) || (flagInfo.CosCloudPtr && flagInfo.GcsPtr) {
		return errors.New("Error: Only one input flag is allowed. Multiple appeared")
	}

	if !(flagInfo.GcsPtr) && !(flagInfo.CosCloudPtr) {
		flagInfo.LocalPtr = true
	}

	if flagInfo.BinaryDiffPtr == "" {
		flagInfo.BinaryTypesSelected = BinaryDiffTypes
	} else {
		binaryTypesSelected := strings.Split(flagInfo.BinaryDiffPtr, ",")
		for _, elem := range binaryTypesSelected {
			if utilities.InArray(elem, BinaryDiffTypes) {
				flagInfo.BinaryTypesSelected = append(flagInfo.BinaryTypesSelected, elem)
			} else if elem != "false" {
				return errors.New("Error: Invalid option for \"-binary\" flag")
			}
		}
	}
	if flagInfo.CompressRootfsFile != "" {
		if res := utilities.FileExists(flagInfo.CompressRootfsFile, "txt"); res == -1 {
			return errors.New("Error: " + flagInfo.CompressRootfsFile + " file does not exist")
		} else if res == 0 {
			return errors.New("Error: " + flagInfo.CompressRootfsFile + " is not a \".txt\" file")
		}
	}
	if flagInfo.CompressStatefulFile != "" {
		if res := utilities.FileExists(flagInfo.CompressStatefulFile, "txt"); res == -1 {
			return errors.New("Error: " + flagInfo.CompressStatefulFile + " file does not exist")
		} else if res == 0 {
			return errors.New("Error: " + flagInfo.CompressStatefulFile + " is not a \".txt\" file")
		}
	}

	if flagInfo.OutputSelected != "terminal" && flagInfo.OutputSelected != "json" {
		return errors.New("Error: \"-output\" flag must be ethier \"terminal\" or \"json\"")
	}

	if len(flag.Args()) < 1 || len(flag.Args()) > 2 {
		return errors.New("Error: Input must be one or two arguments")
	}

	flagInfo.Image1 = flag.Arg(0)
	if len(flag.Args()) == 2 {
		if flag.Arg(0) == flag.Arg(1) {
			return errors.New("Error: Identical image passed in. To analyze single image, pass in one argument")
		}
		flagInfo.Image2 = flag.Arg(1)
	}

	return nil
}

// ParseFlags reads and validates the flags from the command-line
// Input: None (Command-line flags and args)
// Output:
//   (*FlagInfo) flagInfo - A struct that holds input preference from the user
func ParseFlags() (*FlagInfo, error) {
	flagInfo := &FlagInfo{}

	flag.Usage = printUsage
	flag.BoolVar(&flagInfo.LocalPtr, "local", false, "See printUsage for description")
	flag.BoolVar(&flagInfo.GcsPtr, "gcs", false, "")
	flag.BoolVar(&flagInfo.CosCloudPtr, "cos-cloud", false, "")

	flag.StringVar(&flagInfo.ProjectIDPtr, "projectID", "", "")

	flag.StringVar(&flagInfo.BinaryDiffPtr, "binary", "", "")
	flag.BoolVar(&flagInfo.PackageSelected, "package", false, "")
	flag.BoolVar(&flagInfo.CommitSelected, "commit", true, "")
	flag.BoolVar(&flagInfo.ReleaseNotesSelected, "release-notes", true, "")

	flag.BoolVar(&flagInfo.Verbose, "verbose", false, "")
	flag.StringVar(&flagInfo.CompressRootfsFile, "compress-rootfs", "", "")
	flag.StringVar(&flagInfo.CompressStatefulFile, "compress-stateful", "", "")

	flag.StringVar(&flagInfo.OutputSelected, "output", "terminal", "")
	flag.Parse()

	if err := FlagErrorChecking(flagInfo); err != nil {
		printUsage()
		return &FlagInfo{}, err
	}

	if flagInfo.CompressRootfsFile != "" { // Get CompressRootfsslice
		compressRootsBytes, err := ioutil.ReadFile(flagInfo.CompressRootfsFile)
		if err != nil {
			return &FlagInfo{}, fmt.Errorf("failed to read compress-rootfs file %v: %v", flagInfo.CompressRootfsFile, err)
		}
		flagInfo.CompressRootfsSlice = strings.Split(string(compressRootsBytes), "\n")
	} else {
		flagInfo.CompressRootfsSlice = defaultCompressRootfs
	}

	if flagInfo.CompressStatefulFile != "" { // Get CompressStatefulFileSlice
		compressedStatefulBytes, err := ioutil.ReadFile(flagInfo.CompressStatefulFile)
		if err != nil {
			return &FlagInfo{}, fmt.Errorf("failed to read compress-stateful file %v: %v", flagInfo.CompressStatefulFile, err)
		}
		flagInfo.CompressStatefulSlice = strings.Split(string(compressedStatefulBytes), "\n")
	} else {
		flagInfo.CompressStatefulSlice = defaultCompressStateful
	}
	return flagInfo, nil
}

// validateLocalImages ensures the two images are one or two unique boot files
// Input:
//   (string) localPath1 - Local path to the first disk.raw file
//   (string) localPath2 - Local path to the second disk.raw file
// Output: nil on success, else error
func validateLocalImages(localPath1, localPath2 string) error {
	if localPath2 == "" {
		if res := utilities.FileExists(localPath1, "raw"); res == -1 {
			return errors.New("Error: " + localPath1 + " file does not exist")
		} else if res == 0 {
			return errors.New("Error: " + localPath1 + " is not a \".raw\" file")
		}
		return nil
	}

	if res := utilities.FileExists(localPath2, "raw"); res == -1 {
		return errors.New("Error: " + localPath2 + " file does not exist")
	} else if res == 0 {
		return errors.New("Error: " + localPath2 + " is not a \".raw\" file")
	}

	info1, _ := os.Stat(localPath1)
	info2, _ := os.Stat(localPath2)
	if os.SameFile(info1, info2) {
		return errors.New("Error: Identical image passed in. To analyze single image, pass in one argument")
	}
	return nil
}

// GetImages reads in all the flags and handles the input based on its type.
// Input:
//   (*FlagInfo) flagInfo - A struct that holds input preference from the user
// Output:
//   (*ImageInfo) image1 - A struct that stores relevent info for image1
//   (*ImageInfo) image2 - A struct that stores relevent info for image2
func GetImages(flagInfo *FlagInfo) (*ImageInfo, *ImageInfo, error) {
	image1, image2 := &ImageInfo{}, &ImageInfo{}

	// Input Selection
	if flagInfo.GcsPtr {
		gcsPath1, gcsPath2 := flagInfo.Image1, flagInfo.Image2

		if err := image1.GetGcsImage(gcsPath1); err != nil {
			return image1, image2, fmt.Errorf("failed to download image stored on GCS for %s: %v", gcsPath1, err)
		}
		if err := image2.GetGcsImage(gcsPath2); err != nil {
			return image1, image2, fmt.Errorf("failed to download image stored on GCS for %s: %v", gcsPath2, err)
		}
		return image1, image2, nil
	} else if flagInfo.CosCloudPtr {
		if flagInfo.ProjectIDPtr == "" {
			return image1, image2, errors.New("Error: COS-cloud input requires the \"projectID\" flag to be set")
		}
		cosCloudPath1, cosCloudPath2 := flagInfo.Image1, flagInfo.Image2

		if err := image1.GetCosImage(cosCloudPath1, flagInfo.ProjectIDPtr); err != nil {
			return image1, image2, fmt.Errorf("failed to get cos image for %s: %v", cosCloudPath1, err)
		}
		if err := image2.GetCosImage(cosCloudPath2, flagInfo.ProjectIDPtr); err != nil {
			return image1, image2, fmt.Errorf("failed to get cos image for %s: %v", cosCloudPath2, err)
		}
		return image1, image2, nil
	} else if flagInfo.LocalPtr {
		localPath1, localPath2 := flagInfo.Image1, flagInfo.Image2

		if err := validateLocalImages(localPath1, localPath2); err != nil {
			return image1, image2, fmt.Errorf("failed to validate local images: %v", err)
		}
		if err := image1.GetLocalImage(localPath1); err != nil {
			return image1, image2, fmt.Errorf("failed to get local image for %s: %v", localPath1, err)
		}
		if err := image2.GetLocalImage(localPath2); err != nil {
			return image1, image2, fmt.Errorf("failed to get local image for %s: %v", localPath2, err)
		}
		return image1, image2, nil
	}
	return image1, image2, errors.New("Error: At least one flag needs to be true")
}
