/*
 * Copyright 2018-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 core

import (
	"errors"

	"github.com/opencord/openolt-scale-tester/config"
	"github.com/opencord/voltha-lib-go/v3/pkg/log"
	oop "github.com/opencord/voltha-protos/v3/go/openolt"
)

func init() {
	_, _ = log.AddPackage(log.JSON, log.DebugLevel, nil)
}

type WorkFlow interface {
	ProvisionScheds(subs *Subscriber) error
	ProvisionQueues(subs *Subscriber) error
	ProvisionEapFlow(subs *Subscriber) error
	ProvisionDhcpIPV4Flow(subs *Subscriber) error
	ProvisionDhcpIPV6Flow(subs *Subscriber) error
	ProvisionIgmpFlow(subs *Subscriber) error
	ProvisionHsiaFlow(subs *Subscriber) error
	ProvisionVoipFlow(subs *Subscriber) error
	ProvisionVodFlow(subs *Subscriber) error
	ProvisionMgmtFlow(subs *Subscriber) error
	ProvisionMulticastFlow(subs *Subscriber) error
	// TODO: Add new items here as needed.
}

func DeployWorkflow(subs *Subscriber, isGroup bool) {
	var wf = getWorkFlow(subs)

	if isGroup {
		if err := wf.ProvisionMulticastFlow(subs); err != nil {
			subs.Reason = err.Error()
			return
		}
	} else {
		// TODO: Catch and log errors for below items if needed.
		if err := wf.ProvisionScheds(subs); err != nil {
			subs.Reason = err.Error()
			return
		}

		if err := wf.ProvisionQueues(subs); err != nil {
			subs.Reason = err.Error()
			return
		}

		if err := wf.ProvisionEapFlow(subs); err != nil {
			subs.Reason = err.Error()
			return
		}

		if err := wf.ProvisionDhcpIPV4Flow(subs); err != nil {
			subs.Reason = err.Error()
			return
		}

		if err := wf.ProvisionDhcpIPV6Flow(subs); err != nil {
			subs.Reason = err.Error()
			return
		}

		if err := wf.ProvisionIgmpFlow(subs); err != nil {
			subs.Reason = err.Error()
			return
		}

		if err := wf.ProvisionHsiaFlow(subs); err != nil {
			subs.Reason = err.Error()
			return
		}

		if err := wf.ProvisionVoipFlow(subs); err != nil {
			subs.Reason = err.Error()
			return
		}

		if err := wf.ProvisionVodFlow(subs); err != nil {
			subs.Reason = err.Error()
			return
		}

		if err := wf.ProvisionMgmtFlow(subs); err != nil {
			subs.Reason = err.Error()
			return
		}
	}

	subs.Reason = ReasonCodeToReasonString(SUBSCRIBER_PROVISION_SUCCESS)
}

func getWorkFlow(subs *Subscriber) WorkFlow {
	switch subs.TestConfig.WorkflowName {
	case "ATT":
		log.Info("chosen-att-workflow")
		return AttWorkFlow{}
	case "DT":
		log.Info("chosen-dt-workflow")
		return DtWorkFlow{}
	case "TT":
		log.Info("chosen-tt-workflow")
		return TtWorkFlow{}
	// TODO: Add new workflow here
	default:
		log.Errorw("operator-workflow-not-supported-yet", log.Fields{"workflowName": subs.TestConfig.WorkflowName})
	}
	return nil
}

// This function should get called even before provisioning an ONUs to install trap-from-nni flows.
// The flows installed here are not related to any subscribers.
func ProvisionNniTrapFlow(oo oop.OpenoltClient, config *config.OpenOltScaleTesterConfig, rsrMgr *OpenOltResourceMgr) error {
	switch config.WorkflowName {
	case "ATT":
		if err := ProvisionAttNniTrapFlow(oo, config, rsrMgr); err != nil {
			log.Error("error-installing-flow", log.Fields{"err": err})
			return err
		}
	case "DT":
		if err := ProvisionDtNniTrapFlow(oo, config, rsrMgr); err != nil {
			log.Error("error-installing-flow", log.Fields{"err": err})
			return err
		}
	case "TT":
		if err := ProvisionTtNniTrapFlow(oo, config, rsrMgr); err != nil {
			log.Error("error-installing-flow", log.Fields{"err": err})
			return err
		}
	// TODO: Add new items here
	default:
		log.Errorw("operator-workflow-not-supported-yet", log.Fields{"workflowName": config.WorkflowName})
		return errors.New("workflow-not-supported")
	}
	return nil
}
