/*
 * 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";

    private boolean useSecurityGroup = false;

    @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 boolean isSecurityGroupEnabled() {
        return useSecurityGroup;
    }

    @Override
    public void setSecurityGroupEnabled(boolean option) {
        useSecurityGroup = option;
    }

    @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);
            }
        }
    }
}
