/*
Copyright 2019 the original author or authors.

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 main

import (
	"flag"
	"os"
	"strings"
	"time"
)

type Config struct {
	OFControllerEndPoints     multiFlag
	VolthaApiEndPoint         string
	LogLevel                  string
	Banner                    bool
	Version                   bool
	ProbeEndPoint             string
	CpuProfile                string
	MemProfile                string
	DeviceListRefreshInterval time.Duration
	ConnectionRetryDelay      time.Duration
	ConnectionMaxRetries      int
	KVStoreType               string
	KVStoreTimeout            time.Duration
	KVStoreAddress            string
	InstanceID                string
	TraceEnabled              bool
	TraceAgentAddress         string
	LogCorrelationEnabled     bool
}

type multiFlag []string

func (m *multiFlag) String() string {
	return "[" + strings.Join(*m, ", ") + "]"
}

func (m *multiFlag) Set(value string) error {
	*m = append(*m, value)
	return nil
}

func parseCommandLineArguments() (*Config, error) {
	config := Config{}

	flag.BoolVar(&(config.Banner),
		"banner",
		true,
		"display application banner on startup")
	flag.BoolVar(&(config.Version),
		"version",
		false,
		"display application version and exit")
	flag.Var(&config.OFControllerEndPoints,
		"controller",
		"connection to the OF controller specified as host:port")
	flag.Var(&config.OFControllerEndPoints,
		"O",
		"(short) connection to the OF controller specified as host:port")
	flag.StringVar(&(config.VolthaApiEndPoint),
		"voltha",
		"voltha-api-server:50060",
		"connection to the VOLTHA API server specified as host:port")
	flag.StringVar(&(config.VolthaApiEndPoint),
		"A",
		"voltha-api-server:50060",
		"(short) connection to the VOLTHA API server specified as host:port")
	flag.StringVar(&(config.ProbeEndPoint),
		"probe",
		":8080",
		"address and port on which to listen for k8s live and ready probe requests")
	flag.StringVar(&(config.ProbeEndPoint),
		"P",
		":8080",
		"(short) address and port on which to listen for k8s live and ready probe requests")
	flag.StringVar(&(config.CpuProfile),
		"cpuprofile",
		"",
		"write cpu profile to 'file' if specified")
	flag.StringVar(&(config.MemProfile),
		"memprofile",
		"",
		"write memory profile to 'file' if specified")
	flag.DurationVar(&(config.ConnectionRetryDelay),
		"cd",
		3*time.Second,
		"(short) delay to wait before connection establishment retries")
	flag.DurationVar(&(config.ConnectionRetryDelay),
		"connnection-delay",
		3*time.Second,
		"delay to wait before connection establishment retries")
	flag.IntVar(&(config.ConnectionMaxRetries),
		"mr",
		0,
		"(short) number of retries when attempting to estblish a connection, 0 is unlimted")
	flag.IntVar(&(config.ConnectionMaxRetries),
		"connnection-retries",
		0,
		"number of retries when attempting to estblish a connection, 0 is unlimted")
	flag.DurationVar(&(config.DeviceListRefreshInterval),
		"dri",
		1*time.Minute,
		"(short) interval between attempts to synchronize devices from voltha to ofagent")
	flag.DurationVar(&(config.DeviceListRefreshInterval),
		"device-refresh-interval",
		1*time.Minute,
		"interval between attempts to synchronize devices from voltha to ofagent")
	flag.StringVar(&(config.KVStoreType), "kv_store_type", "etcd", "KV store type")

	flag.DurationVar(&(config.KVStoreTimeout), "kv_store_request_timeout", 5*time.Second, "The default timeout when making a kv store request")

	flag.StringVar(&(config.KVStoreAddress), "kv_store_address", "voltha-etcd-cluster-client.voltha.svc.cluster.local:2379", "KV store address")

	flag.StringVar(&(config.LogLevel), "log_level", "WARN", "Log level")

	flag.BoolVar(&(config.TraceEnabled),
		"trace_enabled",
		false,
		"Whether to send logs to tracing agent?")
	flag.StringVar(&(config.TraceAgentAddress),
		"trace_agent_address",
		"127.0.0.1:6831",
		"The address of tracing agent to which span info should be sent.")
	flag.BoolVar(&(config.LogCorrelationEnabled),
		"log_correlation_enabled",
		true,
		"Whether to enrich log statements with fields denoting operation being executed for achieving correlation?")

	containerName := getContainerInfo()
	if len(containerName) > 0 {
		config.InstanceID = containerName
	} else {
		config.InstanceID = "openFlowAgent001"
	}

	return &config, nil
}

func getContainerInfo() string {
	return os.Getenv("HOSTNAME")
}
