/*
 * 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"
	"encoding/json"
	"github.com/golang/protobuf/ptypes/empty"
	flags "github.com/jessevdk/go-flags"
	"github.com/opencord/voltctl/internal/pkg/cli/version"
	"github.com/opencord/voltctl/pkg/format"
	"github.com/opencord/voltha-protos/v4/go/voltha"
	"strings"
)

type VersionDetails struct {
	Version   string `json:"version"`
	GoVersion string `json:"goversion"`
	VcsRef    string `json:"gitcommit"`
	VcsDirty  string `json:"gitdirty"`
	BuildTime string `json:"buildtime"`
	Os        string `json:"os"`
	Arch      string `json:"arch"`
}

type VersionOutput struct {
	Client  VersionDetails `json:"client"`
	Cluster VersionDetails `json:"cluster"`
}

type VersionOpts struct {
	OutputOptions
	ClientOnly bool `long:"clientonly" description:"Display only client version information"`
}

var versionOpts = VersionOpts{}

var versionInfo = VersionOutput{
	Client: VersionDetails{
		Version:   version.Version,
		GoVersion: version.GoVersion,
		VcsRef:    version.VcsRef,
		VcsDirty:  version.VcsDirty,
		Os:        version.Os,
		Arch:      version.Arch,
		BuildTime: version.BuildTime,
	},
	Cluster: VersionDetails{
		Version:   "unknown-version",
		GoVersion: "unknown-goversion",
		VcsRef:    "unknown-vcsref",
		VcsDirty:  "unknown-vcsdirty",
		Os:        "unknown-os",
		Arch:      "unknown-arch",
		BuildTime: "unknown-buildtime",
	},
}

func RegisterVersionCommands(parent *flags.Parser) {
	_, err := parent.AddCommand("version", "display version", "Display client and server version", &versionOpts)
	if err != nil {
		Error.Fatalf("Unable to register version command: %s", err.Error())
	}
}

const ClientOnlyFormat = `Client:
 Version        {{.Version}}
 Go version:    {{.GoVersion}}
 Vcs reference: {{.VcsRef}}
 Vcs dirty:     {{.VcsDirty}}
 Built:         {{.BuildTime}}
 OS/Arch:       {{.Os}}/{{.Arch}}
`

const DefaultFormat = `Client:
 Version        {{.Client.Version}}
 Go version:    {{.Client.GoVersion}}
 Vcs reference: {{.Client.VcsRef}}
 Vcs dirty:     {{.Client.VcsDirty}}
 Built:         {{.Client.BuildTime}}
 OS/Arch:       {{.Client.Os}}/{{.Client.Arch}}

Cluster:
 Version        {{.Cluster.Version}}
 Go version:    {{.Cluster.GoVersion}}
 Vcs feference: {{.Cluster.VcsRef}}
 Vcs dirty:     {{.Cluster.VcsDirty}}
 Built:         {{.Cluster.BuildTime}}
 OS/Arch:       {{.Cluster.Os}}/{{.Cluster.Arch}}
`

func (options *VersionOpts) clientOnlyVersion(args []string) error {
	outputFormat := CharReplacer.Replace(options.Format)
	if outputFormat == "" {
		outputFormat = GetCommandOptionWithDefault("version", "format", ClientOnlyFormat)
	}
	if options.Quiet {
		outputFormat = "{{.Version}}"
	}

	result := CommandResult{
		Format:    format.Format(outputFormat),
		OutputAs:  toOutputType(options.OutputAs),
		NameLimit: options.NameLimit,
		Data:      versionInfo.Client,
	}

	GenerateOutput(&result)
	return nil
}

func (options *VersionOpts) Execute(args []string) error {
	if options.ClientOnly {
		return options.clientOnlyVersion(args)
	}

	conn, err := NewConnection()
	if err != nil {
		return err
	}
	defer conn.Close()

	client := voltha.NewVolthaServiceClient(conn)

	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
	defer cancel()

	voltha, err := client.GetVoltha(ctx, &empty.Empty{})
	if err != nil {
		return nil
	}

	info := make(map[string]interface{})
	err = json.Unmarshal([]byte(voltha.Version), &info)
	if err != nil {
		versionInfo.Cluster.Version = strings.ReplaceAll(voltha.Version, "\n", "")
	} else {
		var ok bool
		if _, ok = info["version"]; ok {
			versionInfo.Cluster.Version = info["version"].(string)
		} else {
			versionInfo.Cluster.Version = "unknown-version"
		}

		if _, ok = info["goversion"]; ok {
			versionInfo.Cluster.GoVersion = info["goversion"].(string)
		} else {
			versionInfo.Cluster.GoVersion = "unknown-goversion"
		}

		if _, ok = info["vcsref"]; ok {
			versionInfo.Cluster.VcsRef = info["vcsref"].(string)
		} else {
			versionInfo.Cluster.VcsRef = "unknown-vcsref"
		}

		if _, ok = info["vcsdirty"]; ok {
			versionInfo.Cluster.VcsDirty = info["vcsdirty"].(string)
		} else {
			versionInfo.Cluster.VcsDirty = "unknown-vcsdirty"
		}

		if _, ok = info["buildtime"]; ok {
			versionInfo.Cluster.BuildTime = info["buildtime"].(string)
		} else {
			versionInfo.Cluster.BuildTime = "unknown-buildtime"
		}

		if _, ok = info["os"]; ok {
			versionInfo.Cluster.Os = info["os"].(string)
		} else {
			versionInfo.Cluster.Os = "unknown-os"
		}

		if _, ok = info["arch"]; ok {
			versionInfo.Cluster.Arch = info["arch"].(string)
		} else {
			versionInfo.Cluster.Arch = "unknown-arch"
		}
	}

	outputFormat := CharReplacer.Replace(options.Format)
	if outputFormat == "" {
		outputFormat = GetCommandOptionWithDefault("version", "format", DefaultFormat)
	}
	if options.Quiet {
		outputFormat = "{{.Client.Version}}"
	}

	result := CommandResult{
		Format:    format.Format(outputFormat),
		OutputAs:  toOutputType(options.OutputAs),
		NameLimit: options.NameLimit,
		Data:      versionInfo,
	}

	GenerateOutput(&result)
	return nil
}
