/*
 * Copyright 2019-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 probe

import (
	"context"
	"encoding/json"
	"github.com/opencord/voltha-lib-go/pkg/common/log"
	"github.com/stretchr/testify/assert"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"testing"
)

func init() {
	log.AddPackage(log.JSON, log.WarnLevel, nil)
}

func TestServiceStatusString(t *testing.T) {
	assert.Equal(t, "Unknown", ServiceStatusUnknown.String(), "ServiceStatusUnknown")
	assert.Equal(t, "Preparing", ServiceStatusPreparing.String(), "ServiceStatusPreparing")
	assert.Equal(t, "Prepared", ServiceStatusPrepared.String(), "ServiceStatusPrepared")
	assert.Equal(t, "Running", ServiceStatusRunning.String(), "ServiceStatusRunning")
	assert.Equal(t, "Stopped", ServiceStatusStopped.String(), "ServiceStatusStopped")
	assert.Equal(t, "Failed", ServiceStatusFailed.String(), "ServiceStatusFailed")
}

func AlwaysTrue(map[string]ServiceStatus) bool {
	return true
}

func AlwaysFalse(map[string]ServiceStatus) bool {
	return false
}

func TestWithFuncs(t *testing.T) {
	p := (&Probe{}).WithReadyFunc(AlwaysTrue).WithHealthFunc(AlwaysFalse)

	assert.NotNil(t, p.readyFunc, "ready func not set")
	assert.True(t, p.readyFunc(nil), "ready func not set correctly")
	assert.NotNil(t, p.healthFunc, "health func not set")
	assert.False(t, p.healthFunc(nil), "health func not set correctly")
}

func TestWithReadyFuncOnly(t *testing.T) {
	p := (&Probe{}).WithReadyFunc(AlwaysTrue)

	assert.NotNil(t, p.readyFunc, "ready func not set")
	assert.True(t, p.readyFunc(nil), "ready func not set correctly")
	assert.Nil(t, p.healthFunc, "health func set")
}

func TestWithHealthFuncOnly(t *testing.T) {
	p := (&Probe{}).WithHealthFunc(AlwaysTrue)

	assert.Nil(t, p.readyFunc, "ready func set")
	assert.NotNil(t, p.healthFunc, "health func not set")
	assert.True(t, p.healthFunc(nil), "health func not set correctly")
}

func TestRegisterOneService(t *testing.T) {
	p := &Probe{}

	p.RegisterService("one")

	assert.Equal(t, 1, len(p.status), "wrong number of services")

	_, ok := p.status["one"]
	assert.True(t, ok, "service not found")
}

func TestRegisterMultipleServices(t *testing.T) {
	p := &Probe{}

	p.RegisterService("one", "two", "three", "four")

	assert.Equal(t, 4, len(p.status), "wrong number of services")

	_, ok := p.status["one"]
	assert.True(t, ok, "service one not found")
	_, ok = p.status["two"]
	assert.True(t, ok, "service two not found")
	_, ok = p.status["three"]
	assert.True(t, ok, "service three not found")
	_, ok = p.status["four"]
	assert.True(t, ok, "service four not found")
}

func TestRegisterMultipleServicesIncremental(t *testing.T) {
	p := &Probe{}

	p.RegisterService("one")
	p.RegisterService("two")
	p.RegisterService("three", "four")

	assert.Equal(t, 4, len(p.status), "wrong number of services")

	_, ok := p.status["one"]
	assert.True(t, ok, "service one not found")
	_, ok = p.status["two"]
	assert.True(t, ok, "service two not found")
	_, ok = p.status["three"]
	assert.True(t, ok, "service three not found")
	_, ok = p.status["four"]
	assert.True(t, ok, "service four not found")
}

func TestRegisterMultipleServicesDuplicates(t *testing.T) {
	p := &Probe{}

	p.RegisterService("one", "one", "one", "two")

	assert.Equal(t, 2, len(p.status), "wrong number of services")

	_, ok := p.status["one"]
	assert.True(t, ok, "service one not found")
	_, ok = p.status["two"]
	assert.True(t, ok, "service two not found")
}

func TestRegisterMultipleServicesDuplicatesIncremental(t *testing.T) {
	p := &Probe{}

	p.RegisterService("one")
	p.RegisterService("one")
	p.RegisterService("one", "two")

	assert.Equal(t, 2, len(p.status), "wrong number of services")

	_, ok := p.status["one"]
	assert.True(t, ok, "service one not found")
	_, ok = p.status["two"]
	assert.True(t, ok, "service two not found")
}

func TestUpdateStatus(t *testing.T) {
	p := &Probe{}

	p.RegisterService("one", "two")
	p.UpdateStatus("one", ServiceStatusRunning)

	assert.Equal(t, ServiceStatusRunning, p.status["one"], "status not set")
	assert.Equal(t, ServiceStatusUnknown, p.status["two"], "status set")
}

func TestRegisterOverwriteStatus(t *testing.T) {
	p := &Probe{}

	p.RegisterService("one", "two")
	p.UpdateStatus("one", ServiceStatusRunning)

	assert.Equal(t, ServiceStatusRunning, p.status["one"], "status not set")
	assert.Equal(t, ServiceStatusUnknown, p.status["two"], "status set")

	p.RegisterService("one", "three")
	assert.Equal(t, 3, len(p.status), "wrong number of services")
	assert.Equal(t, ServiceStatusRunning, p.status["one"], "status overridden")
	assert.Equal(t, ServiceStatusUnknown, p.status["two"], "status set")
	assert.Equal(t, ServiceStatusUnknown, p.status["three"], "status set")
}

func TestDetailzWithServies(t *testing.T) {
	p := (&Probe{}).WithReadyFunc(AlwaysTrue).WithHealthFunc(AlwaysTrue)
	p.RegisterService("one", "two")

	req := httptest.NewRequest("GET", "http://example.com/detailz", nil)
	w := httptest.NewRecorder()
	p.detailzFunc(w, req)
	resp := w.Result()
	body, _ := ioutil.ReadAll(resp.Body)

	assert.Equal(t, http.StatusOK, resp.StatusCode, "invalid status code for no services")
	assert.Equal(t, "application/json", resp.Header.Get("Content-Type"), "wrong content type")
	var vals map[string]string
	err := json.Unmarshal(body, &vals)
	assert.Nil(t, err, "unable to unmarshal values")
	assert.Equal(t, "Unknown", vals["one"], "wrong value")
	assert.Equal(t, "Unknown", vals["two"], "wrong value")
}

func TestReadzNoServices(t *testing.T) {
	p := (&Probe{}).WithReadyFunc(AlwaysTrue)
	req := httptest.NewRequest("GET", "http://example.com/readz", nil)
	w := httptest.NewRecorder()
	p.readzFunc(w, req)
	resp := w.Result()

	assert.Equal(t, http.StatusTeapot, resp.StatusCode, "invalid status code for no services")
}

func TestReadzWithServicesWithTrue(t *testing.T) {
	p := (&Probe{}).WithReadyFunc(AlwaysTrue).WithHealthFunc(AlwaysTrue)
	p.RegisterService("one", "two")

	req := httptest.NewRequest("GET", "http://example.com/readz", nil)
	w := httptest.NewRecorder()
	p.readzFunc(w, req)
	resp := w.Result()
	assert.Equal(t, http.StatusOK, resp.StatusCode, "invalid status code for registered only services")
}

func TestReadzWithServicesWithDefault(t *testing.T) {
	p := &Probe{}
	p.RegisterService("one", "two")

	req := httptest.NewRequest("GET", "http://example.com/readz", nil)
	w := httptest.NewRecorder()
	p.readzFunc(w, req)
	resp := w.Result()
	assert.Equal(t, http.StatusTeapot, resp.StatusCode, "invalid status code for registered only services")
}

func TestReadzNpServicesDefault(t *testing.T) {
	p := &Probe{}

	req := httptest.NewRequest("GET", "http://example.com/readz", nil)
	w := httptest.NewRecorder()
	p.readzFunc(w, req)
	resp := w.Result()
	assert.Equal(t, http.StatusTeapot, resp.StatusCode, "invalid status code")
}

func TestReadzWithServicesDefault(t *testing.T) {
	p := &Probe{}
	p.RegisterService("one", "two")
	p.UpdateStatus("one", ServiceStatusRunning)
	p.UpdateStatus("two", ServiceStatusRunning)

	req := httptest.NewRequest("GET", "http://example.com/readz", nil)
	w := httptest.NewRecorder()
	p.readzFunc(w, req)
	resp := w.Result()
	assert.Equal(t, http.StatusOK, resp.StatusCode, "invalid status code")
}

func TestReadzWithServicesDefaultOne(t *testing.T) {
	p := &Probe{}
	p.RegisterService("one", "two")
	p.UpdateStatus("one", ServiceStatusRunning)

	req := httptest.NewRequest("GET", "http://example.com/readz", nil)
	w := httptest.NewRecorder()
	p.readzFunc(w, req)
	resp := w.Result()
	assert.Equal(t, http.StatusTeapot, resp.StatusCode, "invalid status code")
}

func TestHealthzNoServices(t *testing.T) {
	p := (&Probe{}).WithReadyFunc(AlwaysTrue)
	req := httptest.NewRequest("GET", "http://example.com/healthz", nil)
	w := httptest.NewRecorder()
	p.healthzFunc(w, req)
	resp := w.Result()

	assert.Equal(t, http.StatusTeapot, resp.StatusCode, "invalid status code for no services")
}

func TestHealthzWithServicesWithTrue(t *testing.T) {
	p := (&Probe{}).WithReadyFunc(AlwaysTrue).WithHealthFunc(AlwaysTrue)
	p.RegisterService("one", "two")

	req := httptest.NewRequest("GET", "http://example.com/healthz", nil)
	w := httptest.NewRecorder()
	p.healthzFunc(w, req)
	resp := w.Result()
	assert.Equal(t, http.StatusOK, resp.StatusCode, "invalid status code for registered only services")
}

func TestHealthzWithServicesWithDefault(t *testing.T) {
	p := &Probe{}
	p.RegisterService("one", "two")

	req := httptest.NewRequest("GET", "http://example.com/healthz", nil)
	w := httptest.NewRecorder()
	p.healthzFunc(w, req)
	resp := w.Result()
	assert.Equal(t, http.StatusOK, resp.StatusCode, "invalid status code for registered only services")
}

func TestHealthzNoServicesDefault(t *testing.T) {
	p := &Probe{}

	req := httptest.NewRequest("GET", "http://example.com/healthz", nil)
	w := httptest.NewRecorder()
	p.healthzFunc(w, req)
	resp := w.Result()
	assert.Equal(t, http.StatusTeapot, resp.StatusCode, "invalid status code")
}

func TestHealthzWithServicesDefault(t *testing.T) {
	p := &Probe{}
	p.RegisterService("one", "two")
	p.UpdateStatus("one", ServiceStatusRunning)
	p.UpdateStatus("two", ServiceStatusRunning)

	req := httptest.NewRequest("GET", "http://example.com/healthz", nil)
	w := httptest.NewRecorder()
	p.healthzFunc(w, req)
	resp := w.Result()
	assert.Equal(t, http.StatusOK, resp.StatusCode, "invalid status code")
}

func TestHealthzWithServicesDefaultFailed(t *testing.T) {
	p := &Probe{}
	p.RegisterService("one", "two")
	p.UpdateStatus("one", ServiceStatusFailed)

	req := httptest.NewRequest("GET", "http://example.com/healthz", nil)
	w := httptest.NewRecorder()
	p.healthzFunc(w, req)
	resp := w.Result()
	assert.Equal(t, http.StatusTeapot, resp.StatusCode, "invalid status code")
}

func TestSetFuncsToNil(t *testing.T) {
	p := (&Probe{}).WithReadyFunc(AlwaysTrue).WithHealthFunc(AlwaysFalse)
	p.WithReadyFunc(nil).WithHealthFunc(nil)
	assert.Nil(t, p.readyFunc, "ready func not reset to nil")
	assert.Nil(t, p.healthFunc, "health func not reset to nil")
}

func TestUpdateStatusFromContext(t *testing.T) {
	p := &Probe{}
	p.RegisterService("one")
	ctx := context.WithValue(context.Background(), ProbeContextKey, p)
	UpdateStatusFromContext(ctx, "one", ServiceStatusRunning)

	assert.Equal(t, 1, len(p.status), "wrong number of services")
	_, ok := p.status["one"]
	assert.True(t, ok, "unable to find registered service")
	assert.Equal(t, ServiceStatusRunning, p.status["one"], "status not set correctly from context")

}

func TestUpdateStatusFromNilContext(t *testing.T) {
	p := &Probe{}
	p.RegisterService("one")
	UpdateStatusFromContext(nil, "one", ServiceStatusRunning)

	assert.Equal(t, 1, len(p.status), "wrong number of services")
	_, ok := p.status["one"]
	assert.True(t, ok, "unable to find registered service")
	assert.Equal(t, ServiceStatusUnknown, p.status["one"], "status not set correctly from context")

}

func TestUpdateStatusFromContextWithoutProbe(t *testing.T) {
	p := &Probe{}
	p.RegisterService("one")
	ctx := context.Background()
	UpdateStatusFromContext(ctx, "one", ServiceStatusRunning)

	assert.Equal(t, 1, len(p.status), "wrong number of services")
	_, ok := p.status["one"]
	assert.True(t, ok, "unable to find registered service")
	assert.Equal(t, ServiceStatusUnknown, p.status["one"], "status not set correctly from context")

}

func TestUpdateStatusFromContextWrongType(t *testing.T) {
	p := &Probe{}
	p.RegisterService("one")
	ctx := context.WithValue(context.Background(), ProbeContextKey, "Teapot")
	UpdateStatusFromContext(ctx, "one", ServiceStatusRunning)

	assert.Equal(t, 1, len(p.status), "wrong number of services")
	_, ok := p.status["one"]
	assert.True(t, ok, "unable to find registered service")
	assert.Equal(t, ServiceStatusUnknown, p.status["one"], "status not set correctly from context")
}

func TestUpdateStatusNoRegistered(t *testing.T) {
	p := (&Probe{}).WithReadyFunc(AlwaysTrue).WithHealthFunc(AlwaysFalse)

	p.UpdateStatus("one", ServiceStatusRunning)
	assert.Equal(t, 1, len(p.status), "wrong number of services")
	_, ok := p.status["one"]
	assert.True(t, ok, "unable to find registered service")
	assert.Equal(t, ServiceStatusRunning, p.status["one"], "status not set correctly from context")
}
