/*
 * Copyright 2017 Red Hat Inc.
 *
 * 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 io.enmasse.controller.auth;

import java.util.List;
import java.util.stream.Collectors;

import io.enmasse.address.model.AddressSpace;
import io.enmasse.address.model.Endpoint;
import io.enmasse.controller.common.ControllerKind;
import io.enmasse.k8s.api.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static io.enmasse.controller.common.ControllerReason.CertCreateFailed;
import static io.enmasse.controller.common.ControllerReason.CertCreated;
import static io.enmasse.k8s.api.EventLogger.Type.Normal;
import static io.enmasse.k8s.api.EventLogger.Type.Warning;

/**
 * Manages certificates issuing, revoking etc. for EnMasse services
 */
public class AuthController {
    private static final Logger log = LoggerFactory.getLogger(AuthController.class.getName());

    private final CertManager certManager;
    private final EventLogger eventLogger;

    public AuthController(CertManager certManager,
                          EventLogger eventLogger) {
        this.certManager = certManager;
        this.eventLogger = eventLogger;
    }

    public void issueExternalCertificates(AddressSpace addressSpace) throws Exception {
        for (Endpoint endpoint : addressSpace.getEndpoints()) {
            if (endpoint.getCertProvider().isPresent()) {
                String secretName = endpoint.getCertProvider().get().getSecretName();
                certManager.issueRouteCert(secretName, addressSpace.getNamespace());
            }
        }
    }


    public void issueAddressSpaceCert(final AddressSpace addressSpace)
    {
        try {
            final String addressSpaceCaSecretName = KubeUtil.getAddressSpaceCaSecretName(addressSpace.getNamespace());
            if(!certManager.certExists(addressSpaceCaSecretName)) {
                certManager.createSelfSignedCertSecret(addressSpaceCaSecretName);
                //put crt into address space
                log.info("Issued addressspace ca certificates for {}", addressSpace.getName());
                eventLogger.log(CertCreated, "Created address space CA", Normal, ControllerKind.AddressSpace, addressSpace.getName());
            }
        } catch (Exception e) {
            log.warn("Error issuing addressspace ca certificate", e);
            eventLogger.log(CertCreateFailed, "Error creating certificate",Warning, ControllerKind.AddressSpace, addressSpace.getName());
        }
    }

    public void issueComponentCertificates(AddressSpace addressSpace) {
        try {
            final String caSecretName = KubeUtil.getAddressSpaceCaSecretName(addressSpace.getNamespace());
            List<Cert> certs = certManager.listComponents(addressSpace.getNamespace()).stream()
                    .filter(component -> !certManager.certExists(component))
                    .map(certManager::createCsr)
                    .map(request -> certManager.signCsr(request,
                                                        caSecretName))
                    .map(cert -> {
                        certManager.createSecret(cert, caSecretName);
                        return cert; })
                    .collect(Collectors.toList());

            if (!certs.isEmpty()) {
                log.info("Issued component certificates: {}", certs);
                eventLogger.log(CertCreated, "Created component certificates", Normal, ControllerKind.AddressSpace, addressSpace.getName());
            }
        } catch (Exception e) {
            log.warn("Error issuing component certificates", e);
            eventLogger.log(CertCreateFailed, "Error creating component certificates", Warning, ControllerKind.AddressSpace, addressSpace.getName());
        }
    }
}

@@ -1762,21 +1762,21 @@
     
-for (
+List%3C
 Endpoint
  end
@@ -1771,16 +1771,17 @@
 Endpoint
+%3E
  endpoin
@@ -1785,10 +1785,11 @@
 oint
- :
+s =
  add
@@ -1812,20 +1812,105 @@
 points()
-) %7B%0A
+;%0A        if (endpoints != null) %7B%0A            for (Endpoint endpoint : endpoints) %7B%0A    
         
@@ -1975,16 +1975,20 @@
         
+   
+ 
 String s
@@ -2057,32 +2057,36 @@
                 
+    
 certManager.issu
@@ -2130,32 +2130,50 @@
 etNamespace());%0A
+                %7D%0A
             %7D%0A  

add null-check for endpoint per comment by Carsten Lohmann