/*
 * 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 resourcemanager 

import (
    "encoding/json"
    "errors"
    "fmt"
    "strconv"
    "strings"

    ponrmgr "github.com/opencord/voltha-go/adapters/common/ponresourcemanager"
    "github.com/opencord/voltha-go/common/log"
    "github.com/opencord/voltha-go/db/kvstore"
    "github.com/opencord/voltha-go/db/model"
    "github.com/opencord/voltha-go/protos/openolt"
)

CONST KVSTORE_TIMEOUT = 5
const BASE_PATH_KV_STORE = "service/voltha/openolt/{%s}" // service/voltha/openolt/<device_id>

type OpenOltResourceMgr struct {
    DeviceID    string         //OLT device id
    HostAndPort string         // Host and port of the kv store to connect to
    Args        string         // args
    KVStore     *model.Backend // backend kv store connection handle
    DeviceType  string
    Host        string        // Host ip of the kv store
    Port        int           // port of the kv store
    DevInfo     *openolt.DeviceInfo // device information
    // array of pon resource managers per interface technology
    ResourceMgrs map[uint32]*ponrmgr.PONResourceManager
}

func newKVClient(storeType string, address string, timeout uint32) (kvstore.Client, error) {
    log.Infow("kv-store-type", log.Fields{"store": storeType})
    switch storeType {
    case "consul":
        return kvstore.NewConsulClient(address, int(timeout))
    case "etcd":
        return kvstore.NewEtcdClient(address, int(timeout))
    }
    return nil, errors.New("unsupported-kv-store")
}

func SetKVClient(Backend string, Host string, Port int, DeviceID string) *model.Backend {
    addr := Host + ":" + strconv.Itoa(Port)
    // TODO : Make sure direct call to NewBackend is working fine with backend , currently there is some
    // issue between kv store and backend , core is not calling NewBackend directly
    kvClient, err := newKVClient(Backend, addr, KVSTORE_TIMEOUT) 
    if err != nil {
        log.Fatalw("Failed to init KV client\n", log.Fields{"err": err})
        return nil
    }
    kvbackend := &model.Backend{
        Client:     kvClient,
        StoreType:  Backend,
        Host:       Host,
        Port:       Port,
        Timeout:    KVSTORE_TIMEOUT,
        PathPrefix: fmt.Sprintf(BASE_PATH_KV_STORE, DeviceID)}

    return kvbackend
}

func NewResourceMgr(DeviceID string, HostPort string, DeviceType string, DevInfo *openolt.DeviceInfo) *OpenOltResourceMgr {

    /* init a New resource maanger instance which in turn instantiates pon resource manager
       instances according to technology. Initializes the default resource ranges for all
       the reources.
    */
    var ResourceMgr OpenOltResourceMgr
    log.Debugf("Init new resource manager , host_port: %s, deviceid: %s", HostPort, DeviceID)
    ResourceMgr.HostAndPort = HostPort
    ResourceMgr.DeviceType = DeviceType  
    ResourceMgr.DevInfo = DevInfo
    IpPort := strings.Split(HostPort, ":")
    ResourceMgr.Host = IpPort[0]
    ResourceMgr.Port, _ = strconv.Atoi(IpPort[1])

    Backend := "etcd" /* TODO  remove this once we get backend store from registry*/
    ResourceMgr.KVStore = SetKVClient(Backend, ResourceMgr.Host,
        ResourceMgr.Port, DeviceID)
    if ResourceMgr.KVStore == nil {
        log.Error("Failed to setup KV store")
    }
    Ranges := make(map[string]*openolt.DeviceInfo_DeviceResourceRanges)
    RsrcMgrsByTech := make(map[string]*ponrmgr.PONResourceManager)
    ResourceMgr.ResourceMgrs = make(map[uint32]*ponrmgr.PONResourceManager)

    // TODO self.args = registry('main').get_args()

    /*
       If a legacy driver returns protobuf without any ranges,s synthesize one from
       the legacy global per-device informaiton. This, in theory, is temporary until
       the legacy drivers are upgrade to support pool ranges.
    */
    if DevInfo.Ranges == nil {
        var ranges openolt.DeviceInfo_DeviceResourceRanges
        ranges.Technology = DevInfo.GetTechnology()

        NumPONPorts := DevInfo.GetPonPorts()
        var index uint32
        for index = 0; index < NumPONPorts; index++ {
            ranges.IntfIds = append(ranges.IntfIds, index)
        }

        var Pool *openolt.DeviceInfo_DeviceResourceRanges_Pool
        Pool.Type = openolt.DeviceInfo_DeviceResourceRanges_Pool_ONU_ID
        Pool.Start = DevInfo.OnuIdStart
        Pool.End = DevInfo.OnuIdEnd
        Pool.Sharing = openolt.DeviceInfo_DeviceResourceRanges_Pool_DEDICATED_PER_INTF
        ranges.Pools = append(ranges.Pools, Pool)

        Pool.Type = openolt.DeviceInfo_DeviceResourceRanges_Pool_ALLOC_ID
        Pool.Start = DevInfo.AllocIdStart
        Pool.End = DevInfo.AllocIdEnd
        Pool.Sharing = openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH
        ranges.Pools = append(ranges.Pools, Pool)

        Pool.Type = openolt.DeviceInfo_DeviceResourceRanges_Pool_GEMPORT_ID
        Pool.Start = DevInfo.GemportIdStart
        Pool.End = DevInfo.GemportIdEnd
        Pool.Sharing = openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH
        ranges.Pools = append(ranges.Pools, Pool)

        Pool.Type = openolt.DeviceInfo_DeviceResourceRanges_Pool_FLOW_ID
        Pool.Start = DevInfo.FlowIdStart
        Pool.End = DevInfo.FlowIdEnd
        Pool.Sharing = openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH
        ranges.Pools = append(ranges.Pools, Pool)
    }

    //Create a separate Resource Manager instance for each range. This assumes that
    // each technology is represented by only a single range
    var GlobalPONRsrcMgr *ponrmgr.PONResourceManager
    var err error
    for _, TechRange := range DevInfo.Ranges {
        technology := TechRange.Technology
        log.Debugf("Device info technology %s", technology)
        Ranges[technology] = TechRange
        RsrcMgrsByTech[technology], err = ponrmgr.NewPONResourceManager(technology, DeviceType, DeviceID,
            Backend, ResourceMgr.Host, ResourceMgr.Port)
        if err != nil {
            log.Errorf("Failed to create pon resource manager instacnce for technology %s", technology)
            return nil
        }
        //resource_mgrs_by_tech[technology] = resource_mgr
        if GlobalPONRsrcMgr == nil {
            GlobalPONRsrcMgr = RsrcMgrsByTech[technology]
        }
        for IntfId := range TechRange.IntfIds {
            ResourceMgr.ResourceMgrs[uint32(IntfId)] = RsrcMgrsByTech[technology]
        }
        //self.initialize_device_resource_range_and_pool(resource_mgr, global_resource_mgr, arange)
        InitializeDeviceResourceRangeAndPool(RsrcMgrsByTech[technology], GlobalPONRsrcMgr,
            TechRange, DevInfo)
    }
    // After we have initialized resource ranges, initialize the
    // resource pools accordingly.
    for _, PONRMgr := range RsrcMgrsByTech {
        PONRMgr.InitDeviceResourcePool()
    }
    return &ResourceMgr
}

func InitializeDeviceResourceRangeAndPool(PONRMgr *ponrmgr.PONResourceManager, GlobalPONRMgr *ponrmgr.PONResourceManager,
    TechRange *openolt.DeviceInfo_DeviceResourceRanges, DevInfo *openolt.DeviceInfo) {

    // init the resource range pool according to the sharing type

    log.Debugf("Resource range pool init for technology %s", PONRMgr.Technology)
    //first load from KV profiles
    status := PONRMgr.InitResourceRangesFromKVStore()
    if status == false {
        log.Debugf("Failed to load resource ranges from KV store for tech %s", PONRMgr.Technology)
    }

    /*
       Then apply device specific information. If KV doesn't exist
       or is broader than the device, the device's informationw ill
       dictate the range limits
    */
    log.Debugf("Using device info to init pon resource ranges for tech", PONRMgr.Technology)

    ONUIDStart := DevInfo.OnuIdStart
    ONUIDEnd := DevInfo.OnuIdEnd
    ONUIDShared := openolt.DeviceInfo_DeviceResourceRanges_Pool_DEDICATED_PER_INTF
    ONUIDSharedPoolID := uint32(0)
    AllocIDStart := DevInfo.AllocIdStart
    AllocIDEnd := DevInfo.AllocIdEnd
    AllocIDShared := openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH // TODO EdgeCore/BAL limitation
    AllocIDSharedPoolID := uint32(0)
    GEMPortIDStart := DevInfo.GemportIdStart
    GEMPortIDEnd := DevInfo.GemportIdEnd
    GEMPortIDShared := openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH // TODO EdgeCore/BAL limitation
    GEMPortIDSharedPoolID := uint32(0)
    FlowIDStart := DevInfo.FlowIdStart
    FlowIDEnd := DevInfo.FlowIdEnd
    FlowIDShared := openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH // TODO EdgeCore/BAL limitation
    FlowIDSharedPoolID := uint32(0)

    var GlobalPoolID uint32
    var FirstIntfPoolID uint32
    var SharedPoolID uint32

    for _, FirstIntfPoolID = range TechRange.IntfIds {
        break
    }

    for _, RangePool := range TechRange.Pools {
        if RangePool.Sharing == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH {
            SharedPoolID = GlobalPoolID
        } else if RangePool.Sharing == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_SAME_TECH {
            SharedPoolID = FirstIntfPoolID
        } else {
            SharedPoolID = 0
        }
        if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_ONU_ID {
            ONUIDStart = RangePool.Start
            ONUIDEnd = RangePool.End
            ONUIDShared = RangePool.Sharing
            ONUIDSharedPoolID = SharedPoolID
        } else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_ALLOC_ID {
            AllocIDStart = RangePool.Start
            AllocIDEnd = RangePool.End
            AllocIDShared = RangePool.Sharing
            AllocIDSharedPoolID = SharedPoolID
        } else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_GEMPORT_ID {
            GEMPortIDStart = RangePool.Start
            GEMPortIDEnd = RangePool.End
            GEMPortIDShared = RangePool.Sharing
            GEMPortIDSharedPoolID = SharedPoolID
        } else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_FLOW_ID {
            FlowIDStart = RangePool.Start
            FlowIDEnd = RangePool.End
            FlowIDShared = RangePool.Sharing
            FlowIDSharedPoolID = SharedPoolID
        }
    }

    log.Debugw("Device info init", log.Fields{"technology": TechRange.Technology,
        "onu_id_start": ONUIDStart, "onu_id_end": ONUIDEnd, "onu_id_shared_pool_id": ONUIDSharedPoolID,
        "alloc_id_start": AllocIDStart, "alloc_id_end": AllocIDEnd,
        "alloc_id_shared_pool_id": AllocIDSharedPoolID,
        "gemport_id_start":        GEMPortIDStart, "gemport_id_end": GEMPortIDEnd,
        "gemport_id_shared_pool_id": GEMPortIDSharedPoolID,
        "flow_id_start":             FlowIDStart,
        "flow_id_end_idx":           FlowIDEnd,
        "flow_id_shared_pool_id":    FlowIDSharedPoolID,
        "intf_ids":                  TechRange.IntfIds,
        "uni_id_start":              0,
        "uni_id_end_idx":/*MaxUNIIDperONU()*/ 1})

    PONRMgr.InitDefaultPONResourceRanges(ONUIDStart, ONUIDEnd, ONUIDSharedPoolID,
        AllocIDStart, AllocIDEnd, AllocIDSharedPoolID,
        GEMPortIDStart, GEMPortIDEnd, GEMPortIDSharedPoolID,
        FlowIDStart, FlowIDEnd, FlowIDSharedPoolID, 0, 1,
        DevInfo.PonPorts, TechRange.IntfIds)

    // For global sharing, make sure to refresh both local and global resource manager instances' range

    if ONUIDShared == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH {
        GlobalPONRMgr.UpdateRanges(ponrmgr.ONU_ID_START_IDX, ONUIDStart, ponrmgr.ONU_ID_END_IDX, ONUIDEnd,
            "", 0, nil)
        PONRMgr.UpdateRanges(ponrmgr.ONU_ID_START_IDX, ONUIDStart, ponrmgr.ONU_ID_END_IDX, ONUIDEnd,
            "", 0, GlobalPONRMgr)
    }
    if AllocIDShared == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH {
        GlobalPONRMgr.UpdateRanges(ponrmgr.ALLOC_ID_START_IDX, AllocIDStart, ponrmgr.ALLOC_ID_END_IDX, AllocIDEnd,
            "", 0, nil)

        PONRMgr.UpdateRanges(ponrmgr.ALLOC_ID_START_IDX, AllocIDStart, ponrmgr.ALLOC_ID_END_IDX, AllocIDEnd,
            "", 0, GlobalPONRMgr)
    }
    if GEMPortIDShared == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH {
        GlobalPONRMgr.UpdateRanges(ponrmgr.GEMPORT_ID_START_IDX, GEMPortIDStart, ponrmgr.GEMPORT_ID_END_IDX, GEMPortIDEnd,
            "", 0, nil)
        PONRMgr.UpdateRanges(ponrmgr.GEMPORT_ID_START_IDX, GEMPortIDStart, ponrmgr.GEMPORT_ID_END_IDX, GEMPortIDEnd,
            "", 0, GlobalPONRMgr)
    }
    if FlowIDShared == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH {
        GlobalPONRMgr.UpdateRanges(ponrmgr.FLOW_ID_START_IDX, FlowIDStart, ponrmgr.FLOW_ID_END_IDX, FlowIDEnd,
            "", 0, nil)
        PONRMgr.UpdateRanges(ponrmgr.FLOW_ID_START_IDX, FlowIDStart, ponrmgr.FLOW_ID_END_IDX, FlowIDEnd,
            "", 0, GlobalPONRMgr)
    }

    // Make sure loaded range fits the platform bit encoding ranges
    PONRMgr.UpdateRanges(ponrmgr.UNI_ID_START_IDX, 0, ponrmgr.UNI_ID_END_IDX /* TODO =OpenOltPlatform.MAX_UNIS_PER_ONU-1*/, 1, "", 0, nil)
}

/* TODO
def __del__(self):
        self.log.info("clearing-device-resource-pool")
        for key, resource_mgr in self.resource_mgrs.iteritems():
            resource_mgr.clear_device_resource_pool()

    def assert_pon_id_limit(self, pon_intf_id):
        assert pon_intf_id in self.resource_mgrs

    def assert_onu_id_limit(self, pon_intf_id, onu_id):
        self.assert_pon_id_limit(pon_intf_id)
        self.resource_mgrs[pon_intf_id].assert_resource_limits(onu_id, PONResourceManager.ONU_ID)

    @property
    def max_uni_id_per_onu(self):
        return 0 #OpenOltPlatform.MAX_UNIS_PER_ONU-1, zero-based indexing Uncomment or override to make default multi-uni

    def assert_uni_id_limit(self, pon_intf_id, onu_id, uni_id):
        self.assert_onu_id_limit(pon_intf_id, onu_id)
        self.resource_mgrs[pon_intf_id].assert_resource_limits(uni_id, PONResourceManager.UNI_ID)
*/

func (RsrcMgr *OpenOltResourceMgr) GetONUID(PONIntfID uint32) (uint32, error) {

    // Get ONU id for a provided pon interface ID.

    ONUID, err := RsrcMgr.ResourceMgrs[PONIntfID].GetResourceID(PONIntfID,
        ponrmgr.ONU_ID, 1)
    if err != nil {
        log.Errorf("Failed to get resource for interface %d for type %s",
            PONIntfID, ponrmgr.ONU_ID)
        return ONUID[0], err
    }
    if ONUID != nil {
        RsrcMgr.ResourceMgrs[PONIntfID].InitResourceMap(fmt.Sprintf("%d,%d", PONIntfID, ONUID))
    }

    return ONUID[0], err
}

func (RsrcMgr *OpenOltResourceMgr) GetFlowID(PONIntfID uint32, ONUID uint32, UNIID uint32,
    FlowStoreCookie interface{},
    FlowCategory interface{}) (uint32, error) {

    // Get flow ID for a given pon interface id, onu id and uni id.

    var err error
    FlowPath := fmt.Sprintf("%d,%d,%d", PONIntfID, ONUID, UNIID)
    FlowIDs := RsrcMgr.ResourceMgrs[PONIntfID].GetCurrentFlowIDsForOnu(FlowPath)
    if FlowIDs != nil {
        /* TODO once the flow id info structure is known
                for Flow := range FlowIDs {
                    FlowInfo := RsrcMgr.ResourceMgrs[PONIntfID].GetFlowIDInfo(FlowPath, Flow)
                    for Info := range FlowInfo {
                        if FlowCategory != nil &&
                            Info[FlowCategory] == FlowCategory {
                            return 0, Flow
                        }
                        if FlowStoreCookie != nil &&
                            Info[FlowStoreCookie] == FlowStoreCookie {
                            return 0, Flow
                        }
                    }
                }
        */
    }
    FlowIDs, err = RsrcMgr.ResourceMgrs[PONIntfID].GetResourceID(PONIntfID,
        ponrmgr.FLOW_ID, 1)
    if err != nil {
        log.Errorf("Failed to get resource for interface %d for type %s",
            PONIntfID, ponrmgr.FLOW_ID)
        return FlowIDs[0], err
    }
    if FlowIDs != nil {
        RsrcMgr.ResourceMgrs[PONIntfID].UpdateFlowIDForOnu(FlowPath, FlowIDs[0], true)
    }

    return FlowIDs[0], err
}

func (RsrcMgr *OpenOltResourceMgr) GetAllocID(IntfID uint32, ONUID uint32) uint32 {

    // Get alloc id for a given pon interface id and onu id.
    var err error
    IntfONUID := fmt.Sprintf("%d,%d", IntfID, ONUID)
    AllocID := RsrcMgr.ResourceMgrs[IntfID].GetCurrentAllocIDForOnu(IntfONUID)
    if AllocID != nil {
        // Since we support only one alloc_id for the ONU at the moment,
        // return the first alloc_id in the list, if available, for that
        // ONU.
        return AllocID[0]
    }
    AllocID, err = RsrcMgr.ResourceMgrs[IntfID].GetResourceID(IntfID,
        ponrmgr.ALLOC_ID, 1)

    if AllocID == nil || err != nil {
        log.Error("Failed to allocate alloc id")
        return 0
    }
    // update the resource map on KV store with the list of alloc_id
    // allocated for the pon_intf_onu_id tuple
    err = RsrcMgr.ResourceMgrs[IntfID].UpdateAllocIdsForOnu(IntfONUID, AllocID)
    if err != nil {
        log.Error("Failed to update Alloc ID")
        return 0
    }
    return AllocID[0]
}

func (RsrcMgr *OpenOltResourceMgr) UpdateAllocIdsForOnu(PONPort uint32, ONUID uint32,
    UNIID uint32, AllocID []uint32) error {

    /* update alloc ids in kv store for a given pon interface id,
       onu id and uni id.
    */
    IntfONUID := fmt.Sprintf("%d,%d,%d", PONPort, ONUID, UNIID)
    return RsrcMgr.ResourceMgrs[PONPort].UpdateAllocIdsForOnu(IntfONUID,
        AllocID)
}
func (RsrcMgr *OpenOltResourceMgr) GetCurrentGEMPortIDsForOnu(IntfID uint32, ONUID uint32,
    UNIID uint32) []uint32 {

    /* Get gem ports for given pon interface , onu id and uni id. */

    IntfONUID := fmt.Sprintf("%d,%d,%d", IntfID, ONUID, UNIID)
    GEMPortID := RsrcMgr.ResourceMgrs[IntfID].GetCurrentGEMPortIDsForOnu(IntfONUID)
    if GEMPortID != nil {
        // Since we support only one alloc_id for the ONU at the moment,
        // return the first alloc_id in the list, if available, for that
        // ONU.
        return GEMPortID
    }
    return nil
}

func (RsrcMgr *OpenOltResourceMgr) GetCurrentAllocIDForOnu(IntfID uint32, ONUID uint32) uint32 {

    /* Get alloc ids for given pon interface and onu id. */

    IntfONUID := fmt.Sprintf("%d,%d", IntfID, ONUID)
    AllocID := RsrcMgr.ResourceMgrs[IntfID].GetCurrentAllocIDForOnu(IntfONUID)
    if AllocID != nil {
        // Since we support only one alloc_id for the ONU at the moment,
        // return the first alloc_id in the list, if available, for that
        // ONU.
        return AllocID[0]
    }
    return 0
}

func (RsrcMgr *OpenOltResourceMgr) UpdateGEMportsPonportToOnuMapOnKVStore(GEMPorts []uint32, PonPort uint32,
    ONUID uint32, UNIID uint32) error {

    /* Update onu and uni id associated with the gem port to the kv store. */
    var IntfGEMPortPath string
    Data := fmt.Sprintf("%d %d", ONUID, UNIID)
    for _, GEM := range GEMPorts {
        IntfGEMPortPath = fmt.Sprintf("%d,%d", PonPort, GEM)
        Val, err := json.Marshal(Data)
        if err != nil {
            log.Error("failed to Marshal")
            return err
        }
        // This information is used when packet_indication is received and
        // we need to derive the ONU Id for which the packet arrived based
        // on the pon_intf and gemport available in the packet_indication
        if err = RsrcMgr.KVStore.Put(IntfGEMPortPath, Val); err != nil {
            log.Errorf("Failed to update resource %s", IntfGEMPortPath)
            return err
        }
    }
    return nil
}

func (RsrcMgr *OpenOltResourceMgr) GetONUUNIfromPONPortGEMPort(PONPort uint32, GEMPort uint32) []uint32 {

    /* get the onu and uni id for a given gem port. */
    IntfGEMPortPath := fmt.Sprintf("%d,%d", PONPort, GEMPort)
    var GEMPortIDs []uint32
    var Data string
    Value, err := RsrcMgr.KVStore.Get(IntfGEMPortPath)
    if err == nil {
        if Value != nil {
            Val, _ := kvstore.ToByte(Value.Value)
            if err = json.Unmarshal(Val, &Data); err != nil {
                log.Error("Failed to unmarshal")
                return nil
            }
            IDs := strings.Split(Data, " ")
            for _, port := range IDs {
                Intport, _ := strconv.Atoi(port)
                GEMPortIDs = append(GEMPortIDs, uint32(Intport))
            }
        }
    }
    return GEMPortIDs
}

func (RsrcMgr *OpenOltResourceMgr) GetGEMPortID(PONPort uint32, ONUID uint32,
    UNIID uint32, NumOfPorts uint32) ([]uint32, error) {

    /* Get gem port id for a particular pon port, onu id
       and uni id.
    */

    var err error
    IntfONUID := fmt.Sprintf("%d,%d,%d", PONPort, ONUID, UNIID)

    GEMPortList := RsrcMgr.ResourceMgrs[PONPort].GetCurrentGEMPortIDsForOnu(IntfONUID)
    if GEMPortList != nil {
        return GEMPortList, nil
    }

    GEMPortList, err = RsrcMgr.ResourceMgrs[PONPort].GetResourceID(PONPort,
        ponrmgr.GEMPORT_ID, NumOfPorts)
    if err != nil && GEMPortList == nil {
        log.Errorf("Failed to get gem port id for %s", IntfONUID)
        return nil, err
    }

    // update the resource map on KV store with the list of gemport_id
    // allocated for the pon_intf_onu_id tuple
    err = RsrcMgr.ResourceMgrs[PONPort].UpdateGEMPortIDsForOnu(IntfONUID,
        GEMPortList)
    if err != nil {
        log.Errorf("Failed to update GEM ports to kv store for %s", IntfONUID)
        return nil, err
    }
    RsrcMgr.UpdateGEMportsPonportToOnuMapOnKVStore(GEMPortList, PONPort,
        ONUID, UNIID)
    return GEMPortList, err
}

func (RsrcMgr *OpenOltResourceMgr) UpdateGEMPortIDsForOnu(PONPort uint32, ONUID uint32,
    UNIID uint32, GEMPortList []uint32) error {

    /* Update gemport ids on to kv store for a given pon port,
       onu id and uni id.
    */
    IntfONUID := fmt.Sprintf("%d,%d,%d", PONPort, ONUID, UNIID)
    return RsrcMgr.ResourceMgrs[PONPort].UpdateGEMPortIDsForOnu(IntfONUID,
        GEMPortList)

}
func (RsrcMgr *OpenOltResourceMgr) FreeONUID(IntfID uint32, ONUID []uint32) {

    /* Free onu id for a particular interface.*/
    RsrcMgr.ResourceMgrs[IntfID].FreeResourceID(IntfID, ponrmgr.ONU_ID, ONUID)

    var IntfONUID string
    for _, onu := range ONUID {
        IntfONUID = fmt.Sprintf("%d,%d", IntfID, onu)
        RsrcMgr.ResourceMgrs[IntfID].RemoveResourceMap(IntfONUID)
    }
    return
}

func (RsrcMgr *OpenOltResourceMgr) FreeFlowID(IntfID uint32, ONUID uint32,
    UNIID uint32, FlowID []uint32) {

    /* Free flow id for a given interface, onu id and uni id.*/

    RsrcMgr.ResourceMgrs[IntfID].FreeResourceID(IntfID, ponrmgr.FLOW_ID, FlowID)

    var IntfONUID string
    var err error
    for _, flow := range FlowID {
        IntfONUID = fmt.Sprintf("%d,%d,%d", IntfID, ONUID, UNIID)
        err = RsrcMgr.ResourceMgrs[IntfID].UpdateFlowIDForOnu(IntfONUID, flow, false)
        if err != nil {
            log.Error("Failed to Update flow id infor for %s", IntfONUID)
        }
        RsrcMgr.ResourceMgrs[IntfID].RemoveFlowIDInfo(IntfONUID, flow)
    }
    return
}

func (RsrcMgr *OpenOltResourceMgr) FreePONResourcesForONU(IntfID uint32, ONUID uint32) {

    /* Free pon resources for a given pon interface and onu id. */

    var ONUIDs []uint32
    ONUIDs = append(ONUIDs, ONUID)
    IntfONUID := fmt.Sprintf("%d,%d", IntfID, ONUID)

    AllocIDs := RsrcMgr.ResourceMgrs[IntfID].GetCurrentAllocIDForOnu(IntfONUID)

    RsrcMgr.ResourceMgrs[IntfID].FreeResourceID(IntfID,
        ponrmgr.ALLOC_ID,
        AllocIDs)

    GEMPortIDs := RsrcMgr.ResourceMgrs[IntfID].GetCurrentGEMPortIDsForOnu(IntfONUID)
    RsrcMgr.ResourceMgrs[IntfID].FreeResourceID(IntfID,
        ponrmgr.GEMPORT_ID,
        GEMPortIDs)

    FlowIDs := RsrcMgr.ResourceMgrs[IntfID].GetCurrentFlowIDsForOnu(IntfONUID)
    RsrcMgr.ResourceMgrs[IntfID].FreeResourceID(IntfID,
        ponrmgr.FLOW_ID,
        FlowIDs)
    RsrcMgr.ResourceMgrs[IntfID].FreeResourceID(IntfID,
        ponrmgr.ONU_ID,
        ONUIDs)

    // Clear resource map associated with (pon_intf_id, gemport_id) tuple.
    RsrcMgr.ResourceMgrs[IntfID].RemoveResourceMap(IntfONUID)

    // Clear the ONU Id associated with the (pon_intf_id, gemport_id) tuple.
    for _, GEM := range GEMPortIDs {
        RsrcMgr.KVStore.Delete(fmt.Sprintf("%d,%d", IntfID, GEM))
    }
}

/* TODO once the flow id info structure is known
def is_flow_cookie_on_kv_store(self, intf_id, onu_id, uni_id, flow_store_cookie):
  '''
  Note: For flows which trap from the NNI and not really associated with any particular
  ONU (like LLDP), the onu_id and uni_id is set as -1. The intf_id is the NNI intf_id.
  '''
  intf_onu_id = (intf_id, onu_id, uni_id)
  try:
      flow_ids = self.resource_mgrs[intf_id]. \
          get_current_flow_ids_for_onu(intf_onu_id)
      if flow_ids is not None:
          for flow_id in flow_ids:
              flows = self.get_flow_id_info(intf_id, onu_id, uni_id, flow_id)
              assert (isinstance(flows, list))
              for flow in flows:
                  if flow['flow_store_cookie'] == flow_store_cookie:
                      return True
  except Exception as e:
      self.log.error("error-retrieving-flow-info", e=e)

  return False
*/

