/*
   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")
}
