/*
* Copyright 2022-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 nbi

import (
	"bytes"
	"context"
	"encoding/json"
	"net/http"
	"strconv"

	app "voltha-go-controller/internal/pkg/application"
	"voltha-go-controller/internal/pkg/of"
	common "voltha-go-controller/internal/pkg/types"
	"voltha-go-controller/log"

	"github.com/gorilla/mux"
)

// McastConfig structure
type McastConfig struct {
	MvlanProfileID string `json:"mvlanProfile"`
	IgmpProfileID  string `json:"igmpProfile"`
	IgmpProxyIP    string `json:"igmpProxyIp"`
	OltSerialNum   string `json:"oltSerialNum"`
}

// MvlanProfileCfg structure
type MvlanProfileCfg struct {
	*MvlanProfile `json:"mvlanProfile"`
}

// Mvlan - configurations
type Mvlan struct {
	IngressVlan     int `json:"ingressvlan"`
	EgressVlan      int `json:"egressvlan"`
	EgressInnerVlan int `json:"egressinnervlan"`
}

// MvlanProfile structure
type MvlanProfile struct {
	Name                 string                                `json:"name"`
	Groups               map[string][]string                   `json:"groups"`
	Proxy                map[string]common.MulticastGroupProxy `json:"proxy"`
	OLTSerialNum         []string                              `json:"oltserialnum"`
	ActiveChannelsPerSub int                                   `json:"ActiveChannelsPerSub"`
	Mvlan                of.VlanType                           `json:"mvlan"`
	PonVlan              of.VlanType                           `json:"ponVlan"`
	IsChannelBasedGroup  bool                                  `json:"isChannelBasedGroup"`
}

// IGMPCfg structure
type IGMPCfg struct {
	AppID struct {
		IgmpApp struct {
			Parameters common.IGMPConfig `json:"igmpproxy"`
		} `json:"org.opencord.igmpproxy"`
	} `json:"apps"`
}

// MulticastHandle struct
type MulticastHandle struct {
}

// ServeHTTP to serve http request
func (iph *MulticastHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	logger.Infow(ctx, "Received-northbound-request", log.Fields{"Method": r.Method, "URL": r.URL})
	switch r.Method {
	case cPost:
		iph.AddMvlanInfo(context.Background(), w, r)
	case cDelete:
		iph.DelMvlanInfo(context.Background(), w, r)
	default:
		logger.Warnw(ctx, "Unsupported Method", log.Fields{"Method": r.Method})
	}
}

// AddMvlanInfo to add igmp proxy info
func (iph *MulticastHandle) AddMvlanInfo(cntx context.Context, w http.ResponseWriter, r *http.Request) {
	// Get the payload to process the request
	d := new(bytes.Buffer)
	if _, err := d.ReadFrom(r.Body); err != nil {
		logger.Errorw(ctx, "Error reading buffer", log.Fields{"Reason": err.Error()})
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	// Unmarshal the request into service configuration structure
	req := &Mvlan{}
	if err := json.Unmarshal(d.Bytes(), req); err != nil {
		logger.Errorw(ctx, "Failed to Unmarshal Adding Mvlan Info", log.Fields{"req": req, "Reason": err.Error()})
		http.Error(w, err.Error(), http.StatusConflict)
		return
	}
	logger.Infow(ctx, "Received-northbound-add-mvlanInfo-request", log.Fields{"req": req})

	go iph.addMvlan(cntx, w, req)
}

// DelMvlanInfo to delete igmp proxy info
func (iph *MulticastHandle) DelMvlanInfo(cntx context.Context, w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	egressvlan := vars["egressvlan"]

	name := "mvlan" + egressvlan
	// HTTP response with 202 accepted for service delete request
	w.WriteHeader(http.StatusAccepted)

	logger.Infow(ctx, "Request for DelMvlanInfo for mvlan", log.Fields{"name": name})
	err := app.GetApplication().DelMvlanProfile(cntx, name)
	if err != nil {
		logger.Errorw(cntx, "Failed to delete Mvlan profile", log.Fields{"name": name, "Error": err.Error()})
		w.WriteHeader(http.StatusNotFound)
		return
	}
}

func (iph *MulticastHandle) addMvlan(cntx context.Context, w http.ResponseWriter, req *Mvlan) {
	var config MvlanProfile
	var groups []string

	groups = append(groups, "225.0.0.0-239.255.255.255")
	config.Name = "mvlan" + strconv.Itoa(req.EgressVlan)
	config.Mvlan = of.VlanType(req.EgressVlan)
	config.PonVlan = of.VlanType(req.EgressInnerVlan)
	config.Groups = make(map[string][]string)
	config.Groups["default"] = groups

	logger.Infow(ctx, "northbound-add-mvlan-received", log.Fields{"Config": config})

	if err := app.GetApplication().AddMvlanProfile(cntx, config.Name, config.Mvlan, config.PonVlan, config.Groups,
		config.IsChannelBasedGroup, config.OLTSerialNum,
		255, config.Proxy); err != nil {
		logger.Errorw(ctx, "northbound-add-mvlan-failed", log.Fields{"mvlan": config.Name, "Reason": err.Error()})
		http.Error(w, err.Error(), http.StatusConflict)
		return
	}
	logger.Debugw(ctx, "northbound-add-mvlan-successful", log.Fields{"mvlan": config.Name})
}
