func (c *MecHostController) GetMecHost() {
	log.Info("Query mec host request received.")
	clientIp := c.Ctx.Input.IP()
	err := util.ValidateSrcAddress(clientIp)
	if err != nil {
		c.HandleLoggingForError(clientIp, util.BadRequest, util.ClientIpaddressInvalid)
		return
	}
	c.displayReceivedMsg(clientIp)
	accessToken := c.Ctx.Request.Header.Get(util.AccessToken)
	err = c.ValidateTokenAndCredentials(accessToken, clientIp, "")
	if err != nil {
		return
	}
	var mecHosts []*models.MecHost
	_, _ = c.Db.QueryTable(util.Mec_Host, &mecHosts, "")
	for _, mecHost := range mecHosts {
		_, _ = c.Db.LoadRelated(mecHost, "Hwcapabilities")
	}
	var mecHostsRes []models.MecHostInfo
	res, err := json.Marshal(mecHosts)
	if err != nil {
		c.writeErrorResponse(util.FailedToMarshal, util.BadRequest)
		return
	}
	err = json.Unmarshal(res, &mecHostsRes)
	if err != nil {
		c.writeErrorResponse(util.FailedToUnmarshal, util.BadRequest)
		return
	}
	response, err := json.Marshal(mecHostsRes)
	if err != nil {
		c.writeErrorResponse(util.FailedToMarshal, util.BadRequest)
		return
	}
	_, _ = c.Ctx.ResponseWriter.Write(response)
	c.handleLoggingForSuccess(clientIp, "Query MEC host info is successful")
}
@Title Query MEC hosts
@Description Query mec host information
@Success 200 ok
@Failure 400 bad request
@router /hosts [get]
package controllers
import (
	"encoding/json"
	log "github.com/sirupsen/logrus"
	"lcmcontroller/config"
	"lcmcontroller/models"
	"lcmcontroller/util"
	"strings"
)
type MecHostController struct {
	BaseController
}
func (c *MecHostController) AddMecHost() {
	log.Info("Add or update mec host request received.")
	clientIp := c.Ctx.Input.IP()
	err := util.ValidateSrcAddress(clientIp)
	if err != nil {
		c.HandleLoggingForError(clientIp, util.BadRequest, util.ClientIpaddressInvalid)
		return
	}
	c.displayReceivedMsg(clientIp)
	var request models.MecHostInfo
	err = json.Unmarshal(c.Ctx.Input.RequestBody, &request)
	if err != nil {
		c.writeErrorResponse(util.FailedToUnmarshal, util.BadRequest)
		return
	}
	err = c.ValidateAddMecHostRequest(clientIp, request)
	if err != nil {
		c.writeErrorResponse("failed to add mec host request", util.BadRequest)
		return
	}
	userName, key, err := c.CheckUserNameAndKey(clientIp)
	if err != nil {
		return
	}
	if userName != "" && key != "" {
		err = c.validateCredentials(clientIp, userName, key)
		if err != nil {
			return
		}
	}
	err = c.InsertorUpdateMecHostRecord(clientIp, request)
	if err != nil {
		c.writeErrorResponse("failed to insert or update mec host record", util.BadRequest)
		return
	}
	c.handleLoggingForSuccess(clientIp, "Add or update mec host is successful")
	c.ServeJSON()
}
func (c *MecHostController) UpdateMecHost() {
	log.Info("Add or Update mec host request received.")
	c.AddMecHost()
}
func (c *MecHostController) ValidateAddMecHostRequest(clientIp string, request models.MecHostInfo) error {
	err := util.ValidateIpv4Address(request.MechostIp)
	if err != nil {
		c.HandleLoggingForError(clientIp, util.BadRequest, "MecHost address is invalid")
		return err
	}
	err = c.ValidateMecHostZipCodeCity(request, clientIp)
	if err != nil {
		c.HandleLoggingForError(clientIp, util.BadRequest, "Clientip is invalid")
		return err
	}
	if len(request.Address) > 256 {
		c.HandleLoggingForError(clientIp, util.BadRequest, "Address is invalid")
		return err
	}
	affinity, err := util.ValidateName(request.Affinity, util.AffinityRegex)
	if err != nil || !affinity {
		c.HandleLoggingForError(clientIp, util.BadRequest, "Affinity is invalid")
		return err
	}
	userName, err := util.ValidateName(request.UserName, util.NameRegex)
	if err != nil || !userName {
		c.HandleLoggingForError(clientIp, util.BadRequest, "Username is invalid")
		return err
	}
	if len(request.Coordinates) > 128 {
		c.HandleLoggingForError(clientIp, util.BadRequest, "Coordinates is invalid")
		return err
	}
	vim, err := util.ValidateName(request.Vim, util.NameRegex)
	if err != nil || !vim {
		c.HandleLoggingForError(clientIp, util.BadRequest, "Vim is invalid")
		return err
	}
	originVar, err := util.ValidateName(request.Origin, util.NameRegex)
	if err != nil || !originVar {
		c.HandleLoggingForError(clientIp, util.BadRequest, "Origin is invalid")
		return err
	}
	return nil
}
func (c *MecHostController) InsertorUpdateMecHostRecord(clientIp string, request models.MecHostInfo) error {
	if request.Origin == "" {
		request.Origin = "MEO"
	}
	syncStatus := true
	if request.Origin == "MEPM" {
		syncStatus = false
	}
	hostInfoRecord := &models.MecHost{
		MecHostId:          request.MechostIp,
		MechostIp:          request.MechostIp,
		MechostName:        request.MechostName,
		ZipCode:            request.ZipCode,
		City:               request.City,
		Address:            request.Address,
		Affinity:           request.Affinity,
		UserName:           request.UserName,
		ConfigUploadStatus: "",
		Coordinates:        request.Coordinates,
		Vim:                request.Vim,
		Origin:             request.Origin,
		SyncStatus:         syncStatus,
	}
	count, err := c.Db.QueryCount(util.Mec_Host)
	if err != nil {
		c.HandleLoggingForError(clientIp, util.StatusInternalServerError, err.Error())
		return err
	}
	if count >= util.MaxNumberOfHostRecords {
		c.HandleLoggingForError(clientIp, util.StatusInternalServerError,
			"Maximum number of host records are exceeded")
		return err
	}
	err = c.Db.InsertOrUpdateData(hostInfoRecord, util.HostIp)
	if err != nil && err.Error() != util.LastInsertIdNotSupported {
		c.HandleLoggingForError(clientIp, util.StatusInternalServerError,
			"Failed to save host info record to database.")
		return err
	}
	for _, hwCapRecord := range request.Hwcapabilities {
		capabilityRecord := &models.MecHwCapability{
			MecCapabilityId: hwCapRecord.HwType + request.MechostIp,
			HwType:          hwCapRecord.HwType,
			HwVendor:        hwCapRecord.HwVendor,
			HwModel:         hwCapRecord.HwModel,
			MecHost:         hostInfoRecord,
		}
		err = c.Db.InsertOrUpdateData(capabilityRecord, "mec_capability_id")
		if err != nil && err.Error() != util.LastInsertIdNotSupported {
			c.HandleLoggingForError(clientIp, util.StatusInternalServerError,
				"Failed to save capability info record to database.")
			return err
		}
	}
	return nil
}
func (c *MecHostController) DeleteMecHost() {
	log.Info("Delete mec host request received.")
	clientIp := c.Ctx.Input.IP()
	err := util.ValidateSrcAddress(clientIp)
	if err != nil {
		c.HandleLoggingForError(clientIp, util.BadRequest, util.ClientIpaddressInvalid)
		return
	}
	c.displayReceivedMsg(clientIp)
	hostIp, err := c.getUrlHostIP(clientIp)
	if err != nil {
		c.HandleLoggingForError(clientIp, util.BadRequest, util.ClientIpaddressInvalid)
		return
	}
	userName := c.Ctx.Request.Header.Get("name")
	if userName != "" {
		name, err := util.ValidateUserName(userName, util.NameRegex)
		if err != nil || !name {
			c.HandleLoggingForError(clientIp, util.BadRequest, "username is invalid")
			return
		}
	}
	key := c.Ctx.Request.Header.Get("key")
	if key != "" {
		validKey, err := util.ValidateDbParams(key)
		if err != nil || !validKey {
			c.HandleLoggingForError(clientIp, util.BadRequest, "key is invalid")
			return
		}
	}
	if userName != "" && key != "" {
		err = c.validateCredentials(clientIp, userName, key)
		if err != nil {
			return
		}
	}
	err = c.DeleteHostInfoRecord(clientIp, hostIp)
	if err != nil {
		c.HandleLoggingForError(clientIp, util.BadRequest, util.ClientIpaddressInvalid)
		return
	}
	c.handleLoggingForSuccess(clientIp, "Delete mec host is successful")
	c.ServeJSON()
}
func (c *MecHostController) DeleteHostInfoRecord(clientIp, hostIp string) error {
	var appInstances []*models.AppInfoRecord
	_, _ = c.Db.QueryTable("app_info_record", &appInstances, "mec_host", hostIp)
	for _, appInstance := range appInstances {
		err := c.TerminateApplication(clientIp, appInstance.AppInstanceId)
		if err != nil {
			return err
		}
	}
	hostInfoRecord := &models.MecHost{
		MecHostId: hostIp,
	}
	readErr := c.Db.ReadData(hostInfoRecord, util.HostIp)
	if readErr != nil {
		c.HandleLoggingForError(clientIp, util.StatusNotFound,
			"Mec host info record does not exist in database")
		return readErr
	}
	var origin = hostInfoRecord.Origin
	err := c.Db.DeleteData(hostInfoRecord, util.HostIp)
	if err != nil {
		c.HandleLoggingForError(clientIp, util.StatusInternalServerError, err.Error())
		return err
	}
	mecHostKeyRec := &models.MecHostStaleRec{
		MecHostId: hostIp,
	}
	if strings.EqualFold(origin, "mepm") {
		err = c.Db.InsertOrUpdateData(mecHostKeyRec, util.HostIp)
		if err != nil && err.Error() != util.LastInsertIdNotSupported {
			c.HandleLoggingForError(clientIp, util.StatusInternalServerError, err.Error())
			return err
		}
	}
	return nil
}
func (c *MecHostController) TerminateApplication(clientIp string, appInsId string) error {
	appInfoRecord, err := c.getAppInfoRecord(appInsId, clientIp)
	if err != nil {
		return err
	}
	vim, err := c.GetVim(clientIp, appInfoRecord.MecHost)
	if err != nil {
		return err
	}
	adapter, err := c.GetPluginAdapter(appInfoRecord.DeployType, clientIp, vim)
	if err != nil {
		return err
	}
	_, err = adapter.Terminate(appInfoRecord.MecHost, "", appInfoRecord.AppInstanceId)
	if err != nil {
		c.HandleLoggingForFailure(clientIp, err.Error())
		return err
	}
	acm := config.NewAppConfigMgr(appInfoRecord.AppInstanceId, "", config.AppAuthConfig{}, config.ApplicationConfig{})
	err = acm.DeleteAppAuthConfig(clientIp)
	if err != nil {
		c.HandleLoggingForError(clientIp, util.StatusInternalServerError, err.Error())
		return err
	}
	var origin = appInfoRecord.Origin
	var tenantId = appInfoRecord.TenantId
	err = c.DeleteAppInfoRecord(appInfoRecord.AppInstanceId)
	if err != nil {
		c.HandleLoggingForError(clientIp, util.StatusInternalServerError, err.Error())
		return err
	}
	err = c.DeleteTenantRecord(clientIp, appInfoRecord.TenantId)
	if err != nil {
		return err
	}
	appInsKeyRec := &models.AppInstanceStaleRec{
		AppInstanceId: appInsId,
		TenantId:      tenantId,
	}
	if strings.EqualFold(origin, "mepm") {
		err = c.Db.InsertOrUpdateData(appInsKeyRec, util.AppInsId)
		if err != nil && err.Error() != util.LastInsertIdNotSupported {
			log.Error("Failed to save app instance key record to database.")
			return err
		}
	}
	return nil
}