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