/*
 * Copyright (C) FuseSource, Inc.
 *   http://fusesource.com
 *
 *   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.fusesource.fabric.git.internal;

import java.io.IOException;

import org.apache.curator.framework.CuratorFramework;
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.Service;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.StoredConfig;
import org.fusesource.fabric.git.GitNode;
import org.fusesource.fabric.groups.Group;
import org.fusesource.fabric.groups.GroupListener;
import org.fusesource.fabric.groups.internal.ZooKeeperGroup;
import org.fusesource.fabric.git.FabricGitService;
import org.fusesource.fabric.utils.Closeables;
import org.fusesource.fabric.utils.SystemProperties;
import org.fusesource.fabric.zookeeper.ZkPath;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.fusesource.fabric.zookeeper.utils.ZooKeeperUtils.getSubstitutedData;

@Component(name = "org.fusesource.fabric.git.service", description = "Fabric Git Service", immediate = true)
@Service(FabricGitService.class)
public class FabricGitServiceImpl implements FabricGitService, GroupListener<GitNode> {

    private static final Logger LOGGER = LoggerFactory.getLogger(FabricGitServiceImpl.class);

    @Reference(cardinality = org.apache.felix.scr.annotations.ReferenceCardinality.MANDATORY_UNARY)
	private CuratorFramework curator;

    @Reference(cardinality = org.apache.felix.scr.annotations.ReferenceCardinality.MANDATORY_UNARY)
	private GitService gitService;

    private Group<GitNode> group;

    @Activate
    public void init() {
        group = new ZooKeeperGroup<GitNode>(curator, ZkPath.GIT.getPath(), GitNode.class);
        group.add(this);
        group.start();
    }

    @Deactivate
    public void destroy() {
        Closeables.closeQuitely(group);
        group = null;
    }

    public Git get() throws IOException {
        return gitService.get();
    }

    @Override
    public void groupEvent(Group<GitNode> group, GroupEvent event) {
        switch (event) {
            case CONNECTED:
            case CHANGED:
                updateMasterUrl(group);
                break;
            case DISCONNECTED:
        }
	}

    /**
     * Updates the git master url, if needed.
     * @param group
     */
    private void updateMasterUrl(Group<GitNode> group) {
        String masterUrl = null;
        GitNode master = group.master();
        if (master != null
                && !master.getContainer().equals(System.getProperty(SystemProperties.KARAF_NAME))) {
            masterUrl = master.getUrl();
        }
        try {
            Git git = get();
            StoredConfig config = git.getRepository().getConfig();
            if (masterUrl != null) {
                String currentMasterUrl = config.getString("remote", "origin", "url");
                if (!masterUrl.equals(currentMasterUrl)) {
                    config.setString("remote", "origin", "url", getSubstitutedData(curator, masterUrl));
                    config.setString("remote", "origin", "fetch", "+refs/heads/*:refs/remotes/origin/*");
                    fireRemoteChangedEvent();
                }
            } else {
                config.unsetSection("remote", "origin");
            }
            config.save();
        } catch (Exception e) {
            LOGGER.error("Failed to point origin to the new master.", e);
        }
    }

    private void fireRemoteChangedEvent() {
        if (gitService != null) {
            gitService.onRemoteChanged();
        }
    }
}

@@ -2051,33 +2051,36 @@
 ANDATORY_UNARY)%0A
-%09
+    
 private CuratorF
@@ -2198,17 +2198,20 @@
 _UNARY)%0A
-%09
+    
 private 
@@ -2494,24 +2494,52 @@
 destroy() %7B%0A
+        group.remove(this);%0A
         Clos
@@ -2925,32 +2925,62 @@
 e DISCONNECTED:%0A
+                disconnect();%0A
         %7D%0A%09%7D%0A%0A  
@@ -2977,9 +2977,12 @@
   %7D%0A
-%09
+    
 %7D%0A%0A 
@@ -3034,16 +3034,23 @@
 needed.%0A
+     *%0A
      * @
@@ -4094,24 +4094,24 @@
 eption e) %7B%0A
-
             
@@ -4185,24 +4185,402 @@
    %7D%0A    %7D%0A%0A
+    /**%0A     * Handle disconnection from the group.%0A     */%0A    public void disconnect() %7B%0A        try %7B%0A            Git git = get();%0A            StoredConfig config = git.getRepository().getConfig();%0A            config.unsetSection(%22remote%22, %22origin%22);%0A        %7D catch (Exception e) %7B%0A            LOGGER.error(%22Failed to disconnect from the master repo.%22, e);%0A        %7D%0A    %7D%0A%0A
     private 

Improve handling of service dectivation and disconnection.