package hu.blackbelt.encryption.services.test;

import hu.blackbelt.encryption.services.Encryptor;
import lombok.extern.slf4j.Slf4j;
import org.osgi.service.component.annotations.*;

import java.util.Collection;
import java.util.Map;
import java.util.TreeMap;

@Component(immediate = true, service = ConfigTest.class)
@Slf4j
public class ConfigTest {

    @Reference(policyOption = ReferencePolicyOption.GREEDY, policy = ReferencePolicy.DYNAMIC)
    private volatile hu.blackbelt.encryption.services.ConfigDecryptor configEncryptor;

    private Map<String, Object> originalProperties = new TreeMap<>();

    @Reference(name = "defaultEncryptor", bind = "setEncryptor", updated = "setEncryptor", unbind = "unsetEncryptor", policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.AT_LEAST_ONE, policy = ReferencePolicy.DYNAMIC, target = "(encryptor.alias=default)", fieldOption = FieldOption.UPDATE)
    private volatile Collection<Encryptor> defaultEncryptor = null;

    @Reference(name = "testEncryptor", bind = "setEncryptor", updated = "setEncryptor", unbind = "unsetEncryptor", policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.AT_LEAST_ONE, policy = ReferencePolicy.DYNAMIC, target = "(encryptor.alias=test)", fieldOption = FieldOption.UPDATE)
    private volatile Collection<Encryptor> testEncryptor = null;


    @Activate
    void start(final Map<String, Object> props) {
        originalProperties.putAll(props);

        updateConfig();
    }

    void stop() {
        originalProperties.clear();
    }

    private void updateConfig() {
        log.info("Updating configuration");

        for (final Map.Entry<String, Object> me : originalProperties.entrySet()) {
            final String key = me.getKey();
            final String value = me.getValue() != null ? me.getValue().toString() : null;

            String decrypted = value;
            if (configEncryptor.isEncrypted(value)) {
                decrypted = configEncryptor.decrypt(value);
            }

            log.debug("KEY: " + key + "; VALUE: " + decrypted);
        }
    }

    void setEncryptor(final Encryptor encryptor, final Map<String, Object> props) {
        log.info("BIND/UPDATE default encryptor");
        updateConfig();
    }

    void unsetEncryptor(final Encryptor encryptor) {
        log.info("UNBIND default encryptor");
    }
}

@@ -180,37 +180,8 @@
 *;%0A%0A
-import java.util.Collection;%0A
 impo
@@ -284,327 +284,80 @@
 lass
-)%0A@Slf4j%0Apublic class ConfigTest %7B%0A%0A    @Reference(policyOption = ReferencePolicyOption.GREEDY, policy = ReferencePolicy.DYNAMIC)%0A    private volatile hu.blackbelt.encryption.services.ConfigDecryptor configEncryptor;%0A%0A    private Map%3CString, Object%3E originalProperties = new TreeMap%3C%3E();%0A%0A    @Reference(name = %22default
+, reference = %7B%0A        @Reference(name = %22defaultEncryptor%22, service = 
 Encr
@@ -353,33 +353,38 @@
 vice = Encryptor
-%22
+.class
 , bind = %22setEnc
@@ -395,35 +395,38 @@
 or%22, updated = %22
-set
+update
 Encryptor%22, unbi
@@ -496,57 +496,8 @@
 EDY,
- cardinality = ReferenceCardinality.AT_LEAST_ONE,
  pol
@@ -602,78 +602,14 @@
 ATE)
+,
 %0A    
-private volatile Collection%3CEncryptor%3E defaultEncryptor = null;%0A%0A
     
@@ -642,16 +642,43 @@
 ryptor%22,
+ service = Encryptor.class,
  bind = 
@@ -700,27 +700,30 @@
  updated = %22
-set
+update
 Encryptor%22, 
@@ -797,57 +797,8 @@
 EDY,
- cardinality = ReferenceCardinality.AT_LEAST_ONE,
  pol
@@ -901,138 +901,620 @@
 TE)%0A
-    private volatile Collection%3CEncryptor%3E testEncryptor = null;%0A%0A%0A    @Activate%0A    void start(final Map%3CString, Object%3E props) %7B
+%7D)%0A@Slf4j%0Apublic class ConfigTest %7B%0A%0A    @Reference(policyOption = ReferencePolicyOption.GREEDY, policy = ReferencePolicy.DYNAMIC)%0A    private volatile hu.blackbelt.encryption.services.ConfigDecryptor configEncryptor;%0A%0A    private Map%3CString, Object%3E originalProperties = new TreeMap%3C%3E();%0A%0A    @Activate%0A    void start(final Map%3CString, Object%3E props) %7B%0A        log.info(%22STARTING ConfigTest%22);%0A%0A        originalProperties.putAll(props);%0A%0A        updateConfig();%0A    %7D%0A%0A    @Modified%0A    void update(final Map%3CString, Object%3E props) %7B%0A        log.info(%22UPDATING ConfigTest%22);%0A%0A        originalProperties.clear();
 %0A   
@@ -1576,32 +1576,48 @@
 onfig();%0A    %7D%0A%0A
+    @Deactivate%0A
     void stop() 
@@ -1614,24 +1614,66 @@
 id stop() %7B%0A
+        log.info(%22STOPPING ConfigTest%22);%0A%0A
         orig
@@ -2358,34 +2358,201 @@
 BIND
-/UPDATE default encryptor%22
+ encryptor: %22 + encryptor.getAlias());%0A    %7D%0A%0A    void updateEncryptor(final Encryptor encryptor, final Map%3CString, Object%3E props) %7B%0A        log.info(%22UPDATE encryptor: %22 + encryptor.getAlias()
 );%0A 
@@ -2663,26 +2663,43 @@
 IND 
-default encryptor%22
+encryptor: %22 + encryptor.getAlias()
 );%0A 

update test component