/*
DESCRIPTION
  config_test.go provides testing for the Config struct methods (Validate and Update).

AUTHORS
  Saxon A. Nelson-Milton <saxon@ausocean.org>

LICENSE
  Copyright (C) 2020 the Australian Ocean Lab (AusOcean)

  It is free software: you can redistribute it and/or modify them
  under the terms of the GNU General Public License as published by the
  Free Software Foundation, either version 3 of the License, or (at your
  option) any later version.

  It is distributed in the hope that it will be useful, but WITHOUT
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  for more details.

  You should have received a copy of the GNU General Public License
  along with revid in gpl.txt.  If not, see http://www.gnu.org/licenses.
*/

package config

import (
	"testing"
	"time"

	"bitbucket.org/ausocean/av/codec/codecutil"
	"bitbucket.org/ausocean/utils/logger"
	"github.com/google/go-cmp/cmp"
)

type dumbLogger struct{}

func (dl *dumbLogger) Log(l int8, m string, a ...interface{})  {}
func (dl *dumbLogger) SetLevel(l int8)                         {}
func (dl *dumbLogger) Debug(msg string, args ...interface{})   {}
func (dl *dumbLogger) Info(msg string, args ...interface{})    {}
func (dl *dumbLogger) Warning(msg string, args ...interface{}) {}
func (dl *dumbLogger) Error(msg string, args ...interface{})   {}
func (dl *dumbLogger) Fatal(msg string, args ...interface{})   {}

func TestValidate(t *testing.T) {
	dl := &dumbLogger{}

	want := Config{
		Logger:             dl,
		Input:              defaultInput,
		Outputs:            []uint8{defaultOutput},
		InputCodec:         defaultInputCodec,
		RTPAddress:         defaultRTPAddr,
		CameraIP:           defaultCameraIP,
		BurstPeriod:        defaultBurstPeriod,
		MinFrames:          defaultMinFrames,
		FrameRate:          defaultFrameRate,
		ClipDuration:       defaultClipDuration,
		PSITime:            defaultPSITime,
		FileFPS:            defaultFileFPS,
		RBCapacity:         defaultRBCapacity,
		RBStartElementSize: defaultRBStartElementSize,
		RBWriteTimeout:     defaultRBWriteTimeout,
		MinFPS:             defaultMinFPS,
	}

	got := Config{Logger: dl}
	err := (&got).Validate()
	if err != nil {
		t.Fatalf("did not expect error: %v", err)
	}

	if !cmp.Equal(got, want) {
		t.Errorf("configs not equal\nwant: %v\ngot: %v", want, got)
	}
}

func TestUpdate(t *testing.T) {
	updateMap := map[string]string{
		"AutoWhiteBalance":  "sun",
		"BitDepth":          "3",
		"Bitrate":           "200000",
		"Brightness":        "30",
		"BurstPeriod":       "10",
		"CameraChan":        "2",
		"CameraIP":          "192.168.1.5",
		"CBR":               "true",
		"ClipDuration":      "5",
		"Exposure":          "night",
		"FileFPS":           "30",
		"Filters":           "MOG",
		"FrameRate":         "30",
		"Height":            "300",
		"HorizontalFlip":    "true",
		"HTTPAddress":       "http://address",
		"Input":             "rtsp",
		"InputCodec":        "mjpeg",
		"InputPath":         "/inputpath",
		"logging":           "Error",
		"Loop":              "true",
		"MinFPS":            "30",
		"MinFrames":         "30",
		"MotionDownscaling": "3",
		"MotionHistory":     "4",
		"MotionInterval":    "6",
		"MotionKernel":      "2",
		"MotionMinArea":     "9",
		"MotionPadding":     "8",
		"MotionPixels":      "100",
		"MotionThreshold":   "34",
		"OutputPath":        "/outputpath",
		"Outputs":           "Rtmp,Rtp",
		"Quantization":      "30",
		"RBCapacity":        "100000",
		"RBWriteTimeout":    "50",
		"Rotation":          "180",
		"RTMPURL":           "rtmp://url",
		"RTPAddress":        "ip:port",
		"Saturation":        "-10",
		"VBRBitrate":        "300000",
		"VBRQuality":        "excellent",
		"VerticalFlip":      "true",
		"Width":             "300",
	}

	dl := &dumbLogger{}

	want := Config{
		Logger:            dl,
		AutoWhiteBalance:  "sun",
		BitDepth:          3,
		Bitrate:           200000,
		Brightness:        30,
		BurstPeriod:       10,
		CameraChan:        2,
		CameraIP:          "192.168.1.5",
		CBR:               true,
		ClipDuration:      5 * time.Second,
		Exposure:          "night",
		FileFPS:           30,
		Filters:           []uint{FilterMOG},
		FrameRate:         30,
		Height:            300,
		HorizontalFlip:    true,
		HTTPAddress:       "http://address",
		Input:             InputRTSP,
		InputCodec:        codecutil.MJPEG,
		InputPath:         "/inputpath",
		LogLevel:          logger.Error,
		Loop:              true,
		MinFPS:            30,
		MinFrames:         30,
		MotionDownscaling: 3,
		MotionHistory:     4,
		MotionInterval:    6,
		MotionKernel:      2,
		MotionMinArea:     9,
		MotionPadding:     8,
		MotionPixels:      100,
		MotionThreshold:   34,
		OutputPath:        "/outputpath",
		Outputs:           []uint8{OutputRTMP, OutputRTP},
		Quantization:      30,
		RBCapacity:        100000,
		RBWriteTimeout:    50,
		Rotation:          180,
		RTMPURL:           "rtmp://url",
		RTPAddress:        "ip:port",
		Saturation:        -10,
		VBRBitrate:        300000,
		VBRQuality:        QualityExcellent,
		VerticalFlip:      true,
		Width:             300,
	}

	got := Config{Logger: dl}
	got.Update(updateMap)
	if !cmp.Equal(want, got) {
		t.Errorf("configs not equal\nwant: %v\ngot: %v", want, got)
	}
}