// +build unit

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 cmd

import (
	"bytes"
	"github.com/apache/openwhisk-wskdeploy/utils"
	"github.com/spf13/cobra"
	"github.com/stretchr/testify/assert"
	"os"
	"strings"
	"testing"
)

var rootcalled bool

func functionMock() {
	rootcalled = true
}

type resulter struct {
	Error   error
	Output  string
	Command *cobra.Command
}

func initializeWithRootCmd() *cobra.Command {
	rootcalled = false
	functionMock()
	return RootCmd
}

func fullSetupTest(input string) resulter {
	c := initializeWithRootCmd()
	return fullTester(c, input)
}

func fullTester(c *cobra.Command, input string) resulter {
	buf := new(bytes.Buffer)
	c.SetArgs(strings.Split(input, " "))
	err := c.Execute()
	output := buf.String()
	return resulter{err, output, c}
}

type Auth_flags struct {
	ApiHost    string
	Auth       string
	ApiVersion string
}

var expected_auth_flags Auth_flags

type Input struct {
	CfgFile        string
	Verbose        bool
	ProjectPath    string
	DeploymentPath string
	ManifestPath   string
	Preview        bool
}

var expected_input Input

func initializeParameters() {
	rootcalled = false

	expected_auth_flags.ApiHost = "fake_api_host"
	expected_auth_flags.Auth = "fake_auth"
	expected_auth_flags.ApiVersion = "fake_api_version"

	expected_input.CfgFile = os.Getenv("GOPATH") + "/src/github.com/apache/openwhisk-wskdeploy/tests/dat/wskprops"
	expected_input.Verbose = true
	expected_input.Preview = false
	expected_input.ProjectPath = "fake_project_path"
	expected_input.DeploymentPath = "fake_deployment_path"
	expected_input.ManifestPath = "fake_manifest_path"
}

func checkValidAuthInfo(t *testing.T, expected_auth_flags Auth_flags) {
	assert.Equal(t, expected_auth_flags.ApiHost, utils.Flags.ApiHost, "ApiHost does not match.")
	assert.Equal(t, expected_auth_flags.Auth, utils.Flags.Auth, "Auth does not match.")
	assert.Equal(t, expected_auth_flags.ApiVersion, utils.Flags.ApiVersion, "ApiVersion does not match.")
}

func checkValidInputInfo(t *testing.T, expected_input Input) {
	assert.Equal(t, expected_input.CfgFile, utils.Flags.CfgFile, "CfgFile does not match.")
	assert.Equal(t, expected_input.Verbose, utils.Flags.Verbose, "Verbose does not match.")
	assert.Equal(t, expected_input.Preview, utils.Flags.Preview, "Preview does not match.")
	assert.Equal(t, expected_input.ProjectPath, utils.Flags.ProjectPath, "ProjectPath does not match.")
	assert.Equal(t, expected_input.DeploymentPath, utils.Flags.DeploymentPath, "DeploymentPath does not match.")
	assert.Equal(t, expected_input.ManifestPath, utils.Flags.ManifestPath, "ManifestPath does not match.")
}

func composeCommand(auth Auth_flags, input Input) string {
	cmd := ""
	if len(auth.ApiHost) > 0 {
		cmd = cmd + "--apihost " + auth.ApiHost + " "
	}
	if len(auth.Auth) > 0 {
		cmd = cmd + "--auth " + auth.Auth + " "
	}
	if len(auth.ApiVersion) > 0 {
		cmd = cmd + "--apiversion " + auth.ApiVersion + " "
	}
	if len(input.CfgFile) > 0 {
		cmd = cmd + "--config " + input.CfgFile + " "
	}
	if len(input.ProjectPath) > 0 {
		cmd = cmd + "-p " + input.ProjectPath + " "
	}
	if len(input.ManifestPath) > 0 {
		cmd = cmd + "-m " + input.ManifestPath + " "
	}
	if len(input.DeploymentPath) > 0 {
		cmd = cmd + "-d " + input.DeploymentPath + " "
	}
	if input.Verbose {
		cmd = cmd + "-v "
	}
	return cmd
}

func TestRootCommand(t *testing.T) {
	initializeParameters()
	command := composeCommand(expected_auth_flags, expected_input)
	output := fullSetupTest(command)

	if !rootcalled {
		t.Errorf("Root Function was not called\n out:%v", output.Error)
	}
	checkValidAuthInfo(t, expected_auth_flags)
	checkValidInputInfo(t, expected_input)
}
