/*
 *  Copyright (c) 2019 AT&T Intellectual Property.
 *  Copyright (c) 2018-2019 Nokia.
 *
 *  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.
 *
 *  This source code is part of the near-RT RIC (RAN Intelligent Controller)
 *  platform project (RICP).
 *
 */

package main

import (
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
)

// SupervisionURL is the url where kubernetes posts alive queries
const SupervisionURL = "/supervision/"

// HTTPServer is the VesMgr HTTP server struct
type HTTPServer struct {
	listener net.Listener
}

func (s *HTTPServer) init(address string) *HTTPServer {
	var err error
	s.listener, err = net.Listen("tcp", address)
	if err != nil {
		panic("Cannot listen:" + err.Error())
	}
	return s
}

func (s *HTTPServer) start(notifPath string, notifCh chan []byte, supCh chan chan string) {
	go runHTTPServer(s.listener, notifPath, notifCh, supCh)
}

func (s *HTTPServer) addr() net.Addr {
	return s.listener.Addr()
}

func runHTTPServer(listener net.Listener, xappNotifURL string, notifCh chan []byte, supervisionCh chan chan string) {

	logger.Info("vesmgr http server serving at %s", listener.Addr())

	http.HandleFunc(xappNotifURL, func(w http.ResponseWriter, r *http.Request) {

		switch r.Method {
		case "POST":
			logger.Info("httpServer: POST in %s", xappNotifURL)
			body, err := ioutil.ReadAll(r.Body)
			defer r.Body.Close()
			if err != nil {
				logger.Error("httpServer: Invalid body in POST request")
				return
			}
			notifCh <- body
			return
		default:
			logger.Error("httpServer: Invalid method %s to %s", r.Method, r.URL.Path)
			http.Error(w, "405 method not allowed", http.StatusMethodNotAllowed)
			return
		}
	})

	http.HandleFunc(SupervisionURL, func(w http.ResponseWriter, r *http.Request) {

		switch r.Method {
		case "GET":
			logger.Info("httpServer: GET supervision")
			supervisionAckCh := make(chan string)
			// send supervision to the main loop
			supervisionCh <- supervisionAckCh
			reply := <-supervisionAckCh
			logger.Info("httpServer: supervision ack from the main loop: %s", reply)
			fmt.Fprintf(w, reply)
			return
		default:
			logger.Error("httpServer: invalid method %s to %s", r.Method, r.URL.Path)
			http.Error(w, "405 method not allowed", http.StatusMethodNotAllowed)
			return
		}

	})

	http.Serve(listener, nil)
}
