/*
 * 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"
	"strings"

	"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"
)

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.Current().Grpc.Timeout)
	defer cancel()

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

	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
}
