/*
 * Copyright 2017-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 org.onosproject.openstacknetworking.impl;


import com.google.common.base.Strings;
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.onosproject.core.CoreService;
import org.onosproject.event.ListenerRegistry;
import org.onosproject.openstacknetworking.api.Constants;
import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupAdminService;
import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupEvent;
import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupListener;
import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupService;
import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupStore;
import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupStoreDelegate;
import org.openstack4j.model.network.SecurityGroup;
import org.openstack4j.model.network.SecurityGroupRule;
import org.openstack4j.openstack.networking.domain.NeutronSecurityGroup;
import org.slf4j.Logger;

import java.util.List;
import java.util.Objects;
import java.util.Set;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Provides implementation of administering and interfacing OpenStack security
 * groups.
 */
@Service
@Component(immediate = true)
public class OpenstackSecurityGroupManager
        extends ListenerRegistry<OpenstackSecurityGroupEvent, OpenstackSecurityGroupListener>
        implements OpenstackSecurityGroupAdminService, OpenstackSecurityGroupService {

    protected final Logger log = getLogger(getClass());

    private static final String MSG_SG = "OpenStack security group %s %s";
    private static final String MSG_SG_RULE = "OpenStack security group rule %s %s";

    private static final String MSG_CREATED = "created";
    private static final String MSG_REMOVED = "removed";

    private static final String ERR_NULL_SG = "OpenStack security group cannot be null";
    private static final String ERR_NULL_SG_ID = "OpenStack security group ID cannot be null";
    private static final String ERR_NULL_SG_RULE = "OpenStack security group rule cannot be null";
    private static final String ERR_NULL_SG_RULE_ID = "OpenStack security group rule ID cannot be null";
    private static final String ERR_NOT_FOUND = "not found";
    private static final String ERR_DUPLICATE = "already exist";

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected CoreService coreService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected OpenstackSecurityGroupStore osSecurityGroupStore;

    private final OpenstackSecurityGroupStoreDelegate delegate = new InternalSecurityGroupStoreDelegate();

    @Activate
    protected void activate() {
        coreService.registerApplication(Constants.OPENSTACK_NETWORKING_APP_ID);
        osSecurityGroupStore.setDelegate(delegate);
        log.info("Started");
    }

    @Deactivate
    protected void deactivate() {
        osSecurityGroupStore.unsetDelegate(delegate);
        log.info("Stopped");
    }

    @Override
    public void createSecurityGroup(SecurityGroup sg) {
        checkNotNull(sg, ERR_NULL_SG);
        checkArgument(!Strings.isNullOrEmpty(sg.getId()), ERR_NULL_SG_ID);

        osSecurityGroupStore.createSecurityGroup(sg);
        log.info(String.format(MSG_SG, sg.getId(), MSG_CREATED));
    }

    @Override
    public void updateSecurityGroup(SecurityGroup sg) {
        checkNotNull(sg, ERR_NULL_SG);
        checkArgument(!Strings.isNullOrEmpty(sg.getId()), ERR_NULL_SG_ID);

        osSecurityGroupStore.updateSecurityGroup(sg);
    }

    @Override
    public void removeSecurityGroup(String sgId) {
        checkNotNull(sgId, ERR_NULL_SG_ID);

        osSecurityGroupStore.removeSecurityGroup(sgId);
        log.info(String.format(MSG_SG, sgId, MSG_REMOVED));
    }

    @Override
    public void createSecurityGroupRule(SecurityGroupRule sgRule) {
        checkNotNull(sgRule, ERR_NULL_SG_RULE);
        checkArgument(!Strings.isNullOrEmpty(sgRule.getId()), ERR_NULL_SG_RULE_ID);
        checkArgument(!Strings.isNullOrEmpty(sgRule.getSecurityGroupId()), ERR_NULL_SG_ID);

        synchronized (this) {
            SecurityGroup sg = securityGroup(sgRule.getSecurityGroupId());
            if (sg == null) {
                final String error = String.format(MSG_SG, sgRule.getSecurityGroupId(), ERR_NOT_FOUND);
                throw new IllegalStateException(error);
            }
            if (sg.getRules().stream().anyMatch(rule -> Objects.equals(rule.getId(), sgRule.getId()))) {
                final String error = String.format(MSG_SG_RULE,
                        sgRule.getSecurityGroupId(), ERR_DUPLICATE);
                throw new IllegalStateException(error);
            }

            // FIXME we cannot add element to extend list
            List updatedSgRules = sg.getRules();
            updatedSgRules.add(sgRule);
            SecurityGroup updatedSg = NeutronSecurityGroup.builder().from(sg).build();
            osSecurityGroupStore.updateSecurityGroup(updatedSg);
        }

        log.info(String.format(MSG_SG_RULE, sgRule.getId(), MSG_CREATED));
    }

    @Override
    public void removeSecurityGroupRule(String sgRuleId) {
        checkArgument(!Strings.isNullOrEmpty(sgRuleId), ERR_NULL_SG_RULE_ID);

        synchronized (this) {
            SecurityGroupRule sgRule = securityGroupRule(sgRuleId);
            if (sgRule == null) {
                final String error = String.format(MSG_SG_RULE, sgRuleId, ERR_NOT_FOUND);
                throw new IllegalStateException(error);
            }

            SecurityGroup sg = securityGroup(sgRule.getSecurityGroupId());
            if (sg == null) {
                final String error = String.format(MSG_SG, sgRule.getSecurityGroupId(), ERR_NOT_FOUND);
                throw new IllegalStateException(error);
            }

            if (sg.getRules().stream().noneMatch(rule -> Objects.equals(rule.getId(), sgRule.getId()))) {
                final String error = String.format(MSG_SG_RULE,
                        sgRule.getSecurityGroupId(), ERR_NOT_FOUND);
                throw new IllegalStateException(error);
            }

            // FIXME we cannot handle the element of extend list as a specific class object
            List updatedSgRules = sg.getRules();
            updatedSgRules.removeIf(r -> ((SecurityGroupRule) r).getId().equals(sgRuleId));
            SecurityGroup updatedSg = NeutronSecurityGroup.builder().from(sg).build();
            osSecurityGroupStore.updateSecurityGroup(updatedSg);
        }

        log.info(String.format(MSG_SG_RULE, sgRuleId, MSG_REMOVED));
    }

    @Override
    public Set<SecurityGroup> securityGroups() {
        return osSecurityGroupStore.securityGroups();
    }

    @Override
    public SecurityGroup securityGroup(String sgId) {
        checkArgument(!Strings.isNullOrEmpty(sgId), ERR_NULL_SG_ID);
        return osSecurityGroupStore.securityGroup(sgId);
    }

    @Override
    public void clear() {
        osSecurityGroupStore.clear();
    }

    private SecurityGroupRule securityGroupRule(String sgRuleId) {
        return osSecurityGroupStore.securityGroups().stream()
                .flatMap(sg -> sg.getRules().stream())
                .filter(sgRule -> Objects.equals(sgRule.getId(), sgRuleId))
                .findFirst().orElse(null);
    }

    private class InternalSecurityGroupStoreDelegate implements OpenstackSecurityGroupStoreDelegate {

        @Override
        public void notify(OpenstackSecurityGroupEvent event) {
            if (event != null) {
                log.trace("send openstack security group event {}", event);
                process(event);
            }
        }
    }
}
