/*
 * Copyright 2015 Open Networking Laboratory
 *
 * 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 org.onosproject.vtnrsc.subnet.impl;

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.IpAddress;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.Serializer;
import org.onosproject.store.service.StorageService;
import org.onosproject.vtnrsc.AllocationPool;
import org.onosproject.vtnrsc.DefaultSubnet;
import org.onosproject.vtnrsc.HostRoute;
import org.onosproject.vtnrsc.Subnet;
import org.onosproject.vtnrsc.SubnetId;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.TenantNetworkId;
import org.onosproject.vtnrsc.subnet.SubnetService;
import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
import org.slf4j.Logger;

import java.util.Arrays;
import java.util.Collections;
import java.util.Map;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Provides implementation of the Subnet service.
 */
@Component(immediate = true)
@Service
public class SubnetManager implements SubnetService {

    private static final String SUBNET_ID_NULL = "Subnet ID cannot be null";
    private static final String SUBNET_NOT_NULL = "Subnet cannot be null";
    private static final String SUBNET = "vtn-subnet-store";
    private static final String VTNRSC_APP = "org.onosproject.vtnrsc";


    private final Logger log = getLogger(getClass());

    protected Map<SubnetId, Subnet> subnetStore;
    protected ApplicationId appId;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected StorageService storageService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected CoreService coreService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected TenantNetworkService tenantNetworkService;

    @Activate
    public void activate() {

        appId = coreService.registerApplication(VTNRSC_APP);

        subnetStore = storageService.<SubnetId, Subnet>consistentMapBuilder()
                .withName(SUBNET)
                .withApplicationId(appId)
                .withPurgeOnUninstall()
                .withSerializer(Serializer.using(Arrays.asList(KryoNamespaces.API),
                                                 Subnet.class,
                                                 SubnetId.class,
                                                 TenantNetworkId.class,
                                                 TenantId.class,
                                                 HostRoute.class,
                                                 Subnet.Mode.class,
                                                 AllocationPool.class,
                                                 DefaultSubnet.class,
                                                 IpAddress.Version.class))
                .build().asJavaMap();

        log.info("Started");
    }

    @Deactivate
    public void deactivate() {
        log.info("Stopped");
    }

    @Override
    public Iterable<Subnet> getSubnets() {
        return Collections.unmodifiableCollection(subnetStore.values());
    }

    @Override
    public Subnet getSubnet(SubnetId subnetId) {
        checkNotNull(subnetId, SUBNET_ID_NULL);
        return subnetStore.get(subnetId);
    }

    @Override
    public boolean exists(SubnetId subnetId) {
        checkNotNull(subnetId, SUBNET_ID_NULL);
        return subnetStore.containsKey(subnetId);
    }

    @Override
    public boolean createSubnets(Iterable<Subnet> subnets) {
        checkNotNull(subnets, SUBNET_NOT_NULL);
        for (Subnet subnet : subnets) {
            if (!tenantNetworkService.exists(subnet.networkId())) {
                log.debug("The network identifier that the subnet {} belong to is not exist",
                          subnet.networkId().toString(), subnet.id().toString());
                return false;
            }
            subnetStore.put(subnet.id(), subnet);
            if (!subnetStore.containsKey(subnet.id())) {
                log.debug("The identified subnet whose identifier is {}  create failed",
                          subnet.id().toString());
                return false;
            }
        }
        return true;
    }

    @Override
    public boolean updateSubnets(Iterable<Subnet> subnets) {
        checkNotNull(subnets, SUBNET_NOT_NULL);
        if (subnets != null) {
            for (Subnet subnet : subnets) {
                if (!subnetStore.containsKey(subnet.id())) {
                    log.debug("The subnet is not exist whose identifier is {}",
                              subnet.id().toString());
                    return false;
                }

                subnetStore.put(subnet.id(), subnet);

                if (!subnet.equals(subnetStore.get(subnet.id()))) {
                    log.debug("The subnet is updated failed whose identifier is {}",
                              subnet.id().toString());
                    return false;
                }
            }
        }
        return true;
    }

    @Override
    public boolean removeSubnets(Iterable<SubnetId> subnetIds) {
        checkNotNull(subnetIds, SUBNET_ID_NULL);
        if (subnetIds != null) {
            for (SubnetId subnetId : subnetIds) {
                subnetStore.remove(subnetId);
                if (subnetStore.containsKey(subnetId)) {
                    log.debug("The subnet created is failed whose identifier is {}",
                              subnetId.toString());
                    return false;
                }
            }
        }
        return true;
    }

}
