/*
 * Copyright 2018-present Open Networking Foundation

 * 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 core

import (
	"bytes"
	"context"
	"fmt"
	"os/exec"
	"strconv"
	"time"

	"gerrit.opencord.org/voltha-bbsim/common/logger"
	"gerrit.opencord.org/voltha-bbsim/device"
)

// TestManager is the structure for test manager
type TestManager struct {
	DhcpServerIP string
	Pid          []int
	testers      map[string]map[device.Devkey]*Tester
	ctx          context.Context
	cancel       context.CancelFunc
}

// Tester is the structure for Test
type Tester struct {
	Type     string
	Key      device.Devkey
	Testfunc func(device.Devkey) error
	Waitsec  int
	ctx      context.Context
	cancel   context.CancelFunc
}

// NewTestManager returns new TestManager
func NewTestManager(opt *option) *TestManager {
	t := new(TestManager)
	t.DhcpServerIP = opt.dhcpservip
	return t
}

// CreateTester creates instance of Tester
func (*TestManager) CreateTester(testtype string, opt *option, key device.Devkey, fn func(device.Devkey) error, waitsec int) *Tester {
	logger.Debug("CreateTester() called")
	t := new(Tester)
	t.Type = testtype
	t.Key = key
	t.Testfunc = fn
	t.Waitsec = waitsec
	return t
}

// Start does starting action - Blocking Call
func (tm *TestManager) Start() error {
	ctx, cancel := context.WithCancel(context.Background())
	tm.ctx = ctx
	tm.cancel = cancel
	tm.testers = make(map[string]map[device.Devkey]*Tester)
	tm.testers["AAA"] = map[device.Devkey]*Tester{}
	tm.testers["DHCP"] = map[device.Devkey]*Tester{}
	logger.Info("TestManager start")
	return nil
}

// Stop does stopping action
func (tm *TestManager) Stop() error {
	if tm.cancel != nil {
		tm.cancel()
	}
	tm.Initialize()
	logger.Debug("TestManager Done")
	return nil
}

func (tm *TestManager) StartTester(t *Tester) error {
	testtype := t.Type
	key := t.Key
	waitsec := t.Waitsec

	logger.Debug("StartTester type:%s called with key:%v", testtype, key)
	child, cancel := context.WithCancel(tm.ctx)
	t.ctx = child
	t.cancel = cancel
	go func() error {
		tick := time.NewTicker(time.Second)
		counter := 0
		defer func() {
			tick.Stop()
			logger.Debug("Tester type:%s with key %v Done", testtype, key)
		}()

	L:
		for counter < waitsec {
			select {
			case <-tick.C:
				counter++
				if counter == waitsec { // TODO: This should be fixed
					break L
				}
			case <-child.Done():
				return nil
			}
		}
		err := t.Testfunc(key)
		if err != nil {
			return err
		}
		return nil
	}()

	tm.testers[testtype][key] = t
	return nil
}

// StopTester stops the test
func (tm *TestManager) StopTester(testtype string, key device.Devkey) error {
	ts := tm.testers[testtype][key]
	ts.cancel()
	delete(tm.testers[testtype], key)
	return nil
}

// Initialize test manager
func (tm *TestManager) Initialize() {
	logger.Info("TestManager Initialize () called")
	pids := tm.Pid
	logger.Debug("Runnig Process: %v", pids)
	KillProcesses(pids)
	exec.Command("rm", "/var/run/dhcpd.pid").Run()    // This is for DHCP server activation
	exec.Command("touch", "/var/run/dhcpd.pid").Run() // This is for DHCP server activation
}

// KillProcesses kill process by specified pid
func KillProcesses(pids []int) error {
	for _, pname := range pids {
		killProcess(pname)
	}
	return nil
}

func killProcess(pid int) error {
	err := exec.Command("kill", strconv.Itoa(pid)).Run()
	if err != nil {
		logger.Error("Fail to kill %d: %v", pid, err)
		return err
	}
	logger.Info("Successfully killed %d", pid)
	return nil
}

func activateWPASupplicant(key device.Devkey) (err error) {
	if err = startEAPClient(key.Intfid, key.ID); err != nil {
		errmsg := fmt.Sprintf("Failed to activate WPA Supplicant intfid: %d onuid: %d", key.Intfid, key.ID)
		logger.Error(errmsg)
	}
	logger.Info("Successfuly activateWPASupplicant() for intfid:%d onuid:%d", key.Intfid, key.ID)
	return nil
}

func activateDHCPClient(key device.Devkey) (err error) {
	if err = startDHCPClient(key.Intfid, key.ID); err != nil {
		errmsg := fmt.Sprintf("Failed to activate DHCP client intfid: %d onuid: %d", key.Intfid, key.ID)
		logger.Error(errmsg)
	}
	return nil
}

func activateDHCPServer(veth string, serverip string) error {
	err := exec.Command("ip", "addr", "add", serverip, "dev", veth).Run()
	if err != nil {
		logger.Error("Fail to add ip to %s address: %s", veth, err)
		return err
	}
	err = exec.Command("ip", "link", "set", veth, "up").Run()
	if err != nil {
		logger.Error("Fail to set %s up: %s", veth, err)
		return err
	}
	dhcp := "/usr/local/bin/dhcpd"
	conf := "/etc/dhcp/dhcpd.conf"
	logfile := "/tmp/dhcplog"
	var stderr bytes.Buffer
	cmd := exec.Command(dhcp, "-cf", conf, veth, "-tf", logfile)
	cmd.Stderr = &stderr
	err = cmd.Run()
	if err != nil {
		logger.Error("Fail to activateDHCP Server (): %s, %s", err, stderr.String())
		return err
	}
	logger.Info("DHCP Server is successfully activated !")
	return err
}
