/*
 * Portions copyright 2019-present Open Networking Foundation
 * Original copyright 2019-present Ciena Corporation
 *
 * 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 commands

import (
	"context"
	flags "github.com/jessevdk/go-flags"
	corderrors "github.com/opencord/cordctl/error"
	"time"
)

const (
	DEFAULT_BACKUP_FORMAT = "table{{ .Status }}\t{{ .Checksum }}\t{{ .Chunks }}\t{{ .Bytes }}"
)

type BackupOutput struct {
	Status   string `json:"status"`
	Checksum string `json:"checksum"`
	Chunks   int    `json:"chunks"`
	Bytes    int    `json:"bytes"`
}

type BackupCreate struct {
	OutputOptions
	ChunkSize int `short:"h" long:"chunksize" default:"65536" description:"Chunk size for streaming transfer"`
	Args      struct {
		LocalFileName string
	} `positional-args:"yes" required:"yes"`
}

type BackupRestore struct {
	OutputOptions
	ChunkSize int `short:"h" long:"chunksize" default:"65536" description:"Chunk size for streaming transfer"`
	Args      struct {
		LocalFileName string
	} `positional-args:"yes" required:"yes"`
	CreateURIFunc func() (string, string) // allow override of CreateURIFunc for easy unit testing
}

type BackupOpts struct {
	Create  BackupCreate  `command:"create"`
	Restore BackupRestore `command:"restore"`
}

var backupOpts = BackupOpts{}

func RegisterBackupCommands(parser *flags.Parser) {
	parser.AddCommand("backup", "backup management commands", "Commands to create backups and restore backups", &backupOpts)
}

func (options *BackupCreate) Execute(args []string) error {
	conn, descriptor, err := InitClient(INIT_DEFAULT)
	if err != nil {
		return err
	}
	defer conn.Close()

	ctx := context.Background() // TODO: Implement a sync timeout

	// We might close and reopen the connection befor we do the DownloadFile,
	// so make sure we've downloaded the service descriptor.
	_, err = descriptor.FindSymbol("xos.filetransfer")
	if err != nil {
		return err
	}

	local_name := options.Args.LocalFileName

	// STEP 1: Create backup operation

	backupop := make(map[string]interface{})
	backupop["operation"] = "create"
	err = CreateModel(conn, descriptor, "BackupOperation", backupop)
	if err != nil {
		return err
	}
	conditional_printf(!options.Quiet, "Created backup-create operation id=%d uuid=%s\n", backupop["id"], backupop["uuid"])
	conditional_printf(!options.Quiet, "Waiting for sync ")

	// STEP 2: Wait for the operation to complete

	flags := GM_UNTIL_ENACTED | GM_UNTIL_FOUND | Ternary_uint32(options.Quiet, GM_QUIET, 0)
	conn, completed_backupop, err := GetModelWithRetry(ctx, conn, descriptor, "BackupOperation", backupop["id"].(int32), flags)
	if err != nil {
		return err
	}

	defer conn.Close()

	status := completed_backupop.GetFieldByName("status").(string)
	conditional_printf(!options.Quiet, "\nStatus: %s\n", status)

	// we've failed. leave.
	if status != "created" {
		return corderrors.NewInternalError("BackupOp status is %s", status)
	}

	// STEP 3: Retrieve URI
	backupfile_id := completed_backupop.GetFieldByName("file_id").(int32)
	if backupfile_id == 0 {
		return corderrors.NewInternalError("BackupOp.file_id is not set")
	}

	completed_backupfile, err := GetModel(ctx, conn, descriptor, "BackupFile", backupfile_id)
	if err != nil {
		return err
	}

	uri := completed_backupfile.GetFieldByName("uri").(string)
	conditional_printf(!options.Quiet, "URI %s\n", uri)

	// STEP 4: Download the file

	conditional_printf(!options.Quiet, "Downloading %s\n", local_name)

	h, err := DownloadFile(conn, descriptor, uri, local_name)
	if err != nil {
		return err
	}

	// STEP 5: Verify checksum

	if completed_backupfile.GetFieldByName("checksum").(string) != h.GetChecksum() {
		return corderrors.WithStackTrace(&corderrors.ChecksumMismatchError{
			Actual:   h.GetChecksum(),
			Expected: completed_backupfile.GetFieldByName("checksum").(string)})
	}

	// STEP 6: Show results

	data := make([]BackupOutput, 1)
	data[0].Chunks = h.chunks
	data[0].Bytes = h.bytes
	data[0].Status = h.status
	data[0].Checksum = h.GetChecksum()

	FormatAndGenerateOutput(&options.OutputOptions, DEFAULT_BACKUP_FORMAT, "{{.Status}}", data)

	return nil
}

// Create a file:/// URI to use for storing the file in the core
func CreateDynamicURI() (string, string) {
	remote_name := "cordctl-restore-" + time.Now().Format("20060102T150405Z")
	uri := "file:///var/run/xos/backup/local/" + remote_name
	return remote_name, uri
}

func (options *BackupRestore) Execute(args []string) error {
	conn, descriptor, err := InitClient(INIT_DEFAULT)
	if err != nil {
		return err
	}
	defer conn.Close()

	ctx := context.Background() // TODO: Implement a sync timeout

	local_name := options.Args.LocalFileName

	var remote_name, uri string
	if options.CreateURIFunc != nil {
		remote_name, uri = options.CreateURIFunc()
	} else {
		remote_name, uri = CreateDynamicURI()
	}

	// STEP 1: Upload the file

	h, upload_result, err := UploadFile(conn, descriptor, local_name, uri, options.ChunkSize)
	if err != nil {
		return err
	}

	upload_status := GetEnumValue(upload_result, "status")
	if upload_status != "SUCCESS" {
		return corderrors.NewInternalError("Upload status was %s", upload_status)
	}

	// STEP 2: Verify checksum

	if upload_result.GetFieldByName("checksum").(string) != h.GetChecksum() {
		return corderrors.WithStackTrace(&corderrors.ChecksumMismatchError{
			Expected: h.GetChecksum(),
			Actual:   upload_result.GetFieldByName("checksum").(string)})
	}

	// STEP 2: Create a BackupFile object

	backupfile := make(map[string]interface{})
	backupfile["name"] = remote_name
	backupfile["uri"] = uri
	backupfile["checksum"] = h.GetChecksum()
	err = CreateModel(conn, descriptor, "BackupFile", backupfile)
	if err != nil {
		return err
	}
	conditional_printf(!options.Quiet, "Created backup file %d\n", backupfile["id"])

	// STEP 3: Create a BackupOperation object

	backupop := make(map[string]interface{})
	backupop["operation"] = "restore"
	backupop["file_id"] = backupfile["id"]
	err = CreateModel(conn, descriptor, "BackupOperation", backupop)
	if err != nil {
		return err
	}
	conditional_printf(!options.Quiet, "Created backup-restore operation id=%d uuid=%s\n", backupop["id"], backupop["uuid"])

	conditional_printf(!options.Quiet, "Waiting for completion ")

	// STEP 4: Wait for completion

	flags := GM_UNTIL_ENACTED | GM_UNTIL_FOUND | GM_UNTIL_STATUS | Ternary_uint32(options.Quiet, GM_QUIET, 0)
	queries := map[string]string{"uuid": backupop["uuid"].(string)}
	conn, completed_backupop, err := FindModelWithRetry(ctx, conn, descriptor, "BackupOperation", queries, flags)
	if err != nil {
		return err
	}

	defer conn.Close()

	conditional_printf(!options.Quiet, "\n")

	// STEP 5: Show results

	data := make([]BackupOutput, 1)
	data[0].Checksum = upload_result.GetFieldByName("checksum").(string)
	data[0].Chunks = int(upload_result.GetFieldByName("chunks_received").(int32))
	data[0].Bytes = int(upload_result.GetFieldByName("bytes_received").(int32))

	if completed_backupop.GetFieldByName("status") == "restored" {
		data[0].Status = "SUCCESS"
	} else {
		data[0].Status = "FAILURE"
	}

	FormatAndGenerateOutput(&options.OutputOptions, DEFAULT_BACKUP_FORMAT, "{{.Status}}", data)

	return nil
}
