// Copyright 2016 Open Networking Laboratory
//
// 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 (
	"fmt"
	"github.com/Sirupsen/logrus"
	"github.com/gorilla/mux"
	"github.com/kelseyhightower/envconfig"
	"net/http"
	"strconv"
	"sync"
	"text/template"
	"time"
)

// application application configuration and internal state
type application struct {
	Port           int           `default:"4246" desc:"port on which the service will listen for requests"`
	Listen         string        `default:"0.0.0.0" desc:"IP on which the service will listen for requests"`
	LogLevel       string        `default:"warning" envconfig:"LOG_LEVEL" desc:"log output level"`
	LogFormat      string        `default:"text" envconfig:"LOG_FORMAT" desc:"format of log messages"`
	DHCPLeaseFile  string        `default:"/harvester/dhcpd.leases" envconfig:"DHCP_LEASE_FILE" desc:"lease file to parse for lease information"`
	OutputFile     string        `envconfig:"OUTPUT_FILE" desc:"name of file to output discovered lease in bind9 format"`
	OutputFormat   string        `default:"{{.ClientHostname}}\tIN A {{.IPAddress}}\t; {{.HardwareAddress}}" envconfig:"OUTPUT_FORMAT" desc:"specifies the single entry format when outputing to a file"`
	VerifyLeases   bool          `default:"true" envconfig:"VERIFY_LEASES" desc:"verifies leases with a ping"`
	VerifyTimeout  time.Duration `default:"1s" envconfig:"VERIFY_TIMEOUT" desc:"max timeout (RTT) to wait for verification pings"`
	VerifyWithUDP  bool          `default:"false" envconfig:"VERIFY_WITH_UDP" desc:"use UDP instead of raw sockets for ping verification"`
	QueryPeriod    time.Duration `default:"30s" envconfig:"QUERY_PERIOD" desc:"period at which the DHCP lease file is processed"`
	QuietPeriod    time.Duration `default:"2s" envconfing:"QUIET_PERIOD" desc:"period to wait between accepting parse requests"`
	RequestTimeout time.Duration `default:"10s" envconfig:"REQUEST_TIMEOUT" desc:"period to wait for processing when requesting a DHCP lease database parsing"`
	RNDCUpdate     bool          `default:"false" envconfig:"RNDC_UPDATE" desc:"determines if the harvester reloads the DNS servers after harvest"`
	RNDCAddress    string        `default:"127.0.0.1" envconfig:"RNDC_ADDRESS" desc:"IP address of the DNS server to contact via RNDC"`
	RNDCPort       int           `default:"954" envconfig:"RNDC_PORT" desc:"port of the DNS server to contact via RNDC"`
	RNDCKeyFile    string        `default:"/key/rndc.conf.maas" envconfig:"RNDC_KEY_FILE" desc:"key file, with default, to contact DNS server"`
	RNDCZone       string        `default:"cord.lab" envconfig:"RNDC_ZONE" desc:"zone to reload"`

	log            *logrus.Logger     `ignored:"true"`
	interchange    sync.RWMutex       `ignored:"true"`
	leases         map[string]*Lease  `ignored:"true"`
	byHardware     map[string]*Lease  `ignored:"true"`
	byHostname     map[string]*Lease  `ignored:"true"`
	outputTemplate *template.Template `ignored:"true"`
	requests       chan *chan uint    `ignored:"true"`
}

func main() {
	// initialize application state
	app := &application{
		log:      logrus.New(),
		requests: make(chan *chan uint, 100),
	}

	// process and validate the application configuration
	err := envconfig.Process("HARVESTER", app)
	if err != nil {
		app.log.Fatalf("unable to parse configuration options : %s", err)
	}
	switch app.LogFormat {
	case "json":
		app.log.Formatter = &logrus.JSONFormatter{}
	default:
		app.log.Formatter = &logrus.TextFormatter{
			FullTimestamp: true,
			ForceColors:   true,
		}
	}
	level, err := logrus.ParseLevel(app.LogLevel)
	if err != nil {
		level = logrus.WarnLevel
	}
	app.log.Level = level

	app.outputTemplate, err = template.New("harvester").Parse(app.OutputFormat)
	if err != nil {
		app.log.Fatalf("invalid output file format specified : %s", err)
	}

	// output the configuration
	app.log.Infof(`Configuration:
           LISTEN:          %s
           PORT:            %d
           LOG_LEVEL:       %s
           LOG_FORMAT:      %s
           DHCP_LEASE_FILE: %s
           OUTPUT_FILE:     %s
           OUTPUT_FORMAT:   %s
           VERIFY_LEASES:   %t
           VERIFY_TIMEOUT:  %s
           VERIFY_WITH_UDP: %t
           QUERY_PERIOD:    %s
           QUIET_PERIOD:    %s
           REQUEST_TIMEOUT: %s
           RNDC_UPDATE:     %t
           RNDC_ADDRESS:    %s
           RNDC_PORT:       %d
           RNDC_KEY_FILE:   %s
           RNDC_ZONE:       %s`,
		app.Listen, app.Port,
		app.LogLevel, app.LogFormat,
		app.DHCPLeaseFile, app.OutputFile, strconv.Quote(app.OutputFormat),
		app.VerifyLeases, app.VerifyTimeout, app.VerifyWithUDP,
		app.QueryPeriod, app.QuietPeriod, app.RequestTimeout,
		app.RNDCUpdate, app.RNDCAddress, app.RNDCPort, app.RNDCKeyFile, app.RNDCZone)

	// establish REST end points
	router := mux.NewRouter()
	router.HandleFunc("/lease/", app.listLeasesHandler).Methods("GET")
	router.HandleFunc("/lease/{ip}", app.getLeaseHandler).Methods("GET")
	router.HandleFunc("/lease/hardware/{mac}", app.getLeaseByHardware).Methods("GET")
	router.HandleFunc("/lease/hostname/{name}", app.getLeaseByHostname).Methods("GET")
	router.HandleFunc("/harvest/", app.doHarvestHandler).Methods("POST")
	router.HandleFunc("/harvest", app.doHarvestHandler).Methods("POST")
	http.Handle("/", router)

	// start DHCP lease file synchronization handler
	go app.syncRequestHandler(app.requests)

	// start loop to periodically synchronize DHCP lease file
	go app.syncFromDHCPLeaseFileLoop(app.requests)

	// listen for REST requests
	http.ListenAndServe(fmt.Sprintf("%s:%d", app.Listen, app.Port), nil)
}
