/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.apache.aries.rsa.discovery.mdns;

import static org.osgi.framework.Constants.FRAMEWORK_UUID;
import static org.osgi.service.jaxrs.runtime.JaxrsServiceRuntimeConstants.JAX_RS_SERVICE_ENDPOINT;

import java.io.IOException;
import java.net.InetAddress;
import java.net.URI;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import javax.jmdns.JmDNS;
import javax.jmdns.ServiceEvent;
import javax.jmdns.ServiceInfo;
import javax.jmdns.ServiceListener;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;

import org.apache.aries.rsa.spi.EndpointDescriptionParser;
import org.apache.aries.rsa.util.StringPlus;
import org.osgi.framework.BundleContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.osgi.service.jaxrs.client.SseEventSourceFactory;
import org.osgi.service.jaxrs.runtime.JaxrsServiceRuntime;
import org.osgi.service.jaxrs.runtime.dto.RuntimeDTO;
import org.osgi.service.remoteserviceadmin.EndpointEventListener;
import org.osgi.service.remoteserviceadmin.EndpointListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SuppressWarnings("deprecation")
@org.apache.aries.rsa.annotations.RSADiscoveryProvider(protocols = "aries.mdns")
@Component
public class MdnsDiscovery {

	private static final String _ARIES_DISCOVERY_HTTP_TCP_LOCAL = "_aries-discovery._tcp.local.";

	private static final Logger LOG = LoggerFactory.getLogger(MdnsDiscovery.class);
	
	private final Client client;
	
	private final String fwUuid;
	
	private final InterestManager interestManager;
	
	private final PublishingEndpointListener publishingListener;
	
	private JaxrsServiceRuntime runtime;
	
	private JmDNS jmdns;


	@Activate
	public MdnsDiscovery(BundleContext ctx, @Reference SseEventSourceFactory eventSourceFactory,
			@Reference ClientBuilder clientBuilder, @Reference EndpointDescriptionParser parser) {
		this.client = clientBuilder.build();
		this.interestManager = new InterestManager(eventSourceFactory, parser, client);
		fwUuid = ctx.getProperty(FRAMEWORK_UUID);
		this.publishingListener = new PublishingEndpointListener(parser, ctx, fwUuid);
	}
    
    @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
    public void bindEndpointEventListener(EndpointEventListener epListener, Map<String, Object> props) {
        interestManager.bindEndpointEventListener(epListener, props);
    }

    public void updatedEndpointEventListener(Map<String, Object> props) {
        interestManager.updatedEndpointEventListener(props);
    }

    public void unbindEndpointEventListener(Map<String, Object> props) {
        interestManager.unbindEndpointEventListener(props);
    }

    @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
    public void bindEndpointListener(EndpointListener epListener, Map<String, Object> props) {
        interestManager.bindEndpointListener(epListener, props);
    }

    public void updatedEndpointListener(Map<String, Object> props) {
        interestManager.updatedEndpointListener(props);
    }

    public void unbindEndpointListener(Map<String, Object> props) {
    	interestManager.unbindEndpointListener(props);
    }

    @Reference(policy = ReferencePolicy.DYNAMIC)
    public void bindJaxrsServiceRuntime(JaxrsServiceRuntime runtime) {
    	updateAndRegister(runtime);
    }

	public void updatedJaxrsServiceRuntime(JaxrsServiceRuntime runtime) {
		updateAndRegister(runtime);
	}

	public void unbindJaxrsServiceRuntime(JaxrsServiceRuntime runtime) {
		JmDNS jmdns = null;
    	synchronized (this) {
    		if(runtime == this.runtime) {
    			jmdns = this.jmdns;
    			this.runtime = null;
    		}
		}
    	
    	if(jmdns != null) {
    		jmdns.unregisterAllServices();
    	}
	}

	private void updateAndRegister(JaxrsServiceRuntime runtime) {
		JmDNS jmdns;
    	synchronized (this) {
    		this.runtime = runtime;
			jmdns = this.jmdns;
		}
    	
    	if(jmdns != null) {
    		RuntimeDTO runtimeDTO = runtime.getRuntimeDTO();
    		List<String> uris = StringPlus.normalize(runtimeDTO.serviceDTO.properties.get(JAX_RS_SERVICE_ENDPOINT));
    		
    		if(uris == null || uris.isEmpty()) {
    			LOG.warn("Unable to advertise discovery as there are no endpoint URIs");
    			return;
    		}
    		
    		String base = runtimeDTO.defaultApplication.base;
    		if(base == null) {
    			base = "";
    		}
    		
    		base += "/aries/rsa/discovery";
    		
    		URI uri = uris.stream()
    			.filter(s -> s.matches(".*(?:[0-9]{1,3}\\.){3}[0-9]{1,3}.*"))
    			.findFirst()
    			.map(URI::create)
    			.orElseGet(() -> URI.create(uris.get(0)));
    		
    		Map<String, Object> props = new HashMap<>();
    		props.put("scheme", uri.getScheme() == null ? "" : uri.getScheme());
    		props.put("path", uri.getPath() == null ? base : uri.getPath() + base);
    		props.put("frameworkUuid", fwUuid);
    		
    		ServiceInfo info = ServiceInfo.create(_ARIES_DISCOVERY_HTTP_TCP_LOCAL, fwUuid, uri.getPort(), 0, 0, props);
    		
    		try {
    			jmdns.registerService(info);
    		} catch (IOException ioe) {
    			LOG.error("Unable to advertise discovery", ioe);
    		}
    	}
	}
    
    public static @interface Config {
    	public String bind_address();
    }
    
    @Activate
    public void start(Config config) throws UnknownHostException, IOException {

    	String bind = config.bind_address();
    	
	    JmDNS jmdns = JmDNS.create(bind == null ? null : InetAddress.getByName(bind));
	    
	    JaxrsServiceRuntime runtime;
	    synchronized (this) {
			this.jmdns = jmdns;
			runtime = this.runtime;
		}
	    
	    if(runtime != null) {
	    	updateAndRegister(runtime);
	    }
	
	    // Add a service listener
	    jmdns.addServiceListener(_ARIES_DISCOVERY_HTTP_TCP_LOCAL, new MdnsListener());
	    
    }
    
    @Deactivate
    public void stop () {
    	try {
			jmdns.close();
		} catch (IOException e) {
			LOG.warn("An exception occurred closing the mdns discovery");
		}
    	
    	interestManager.deactivate();
    	publishingListener.stop();
    }

	private class MdnsListener implements ServiceListener {
		
		private final ConcurrentMap<String, String> namesToUris = new ConcurrentHashMap<>();
		
		@Override
		public void serviceAdded(ServiceEvent event) {
		}
		
		@Override
		public void serviceRemoved(ServiceEvent event) {
			ServiceInfo info = event.getInfo();
			if(info != null) {
				String removed = namesToUris.remove(info.getKey());
				if(removed != null) {
					interestManager.remoteRemoved(removed);
				}
			}
		}
		
		@Override
		public void serviceResolved(ServiceEvent event) {
			ServiceInfo info = event.getInfo();
			
			String infoUuid = info.getPropertyString("frameworkUuid");
			
			if(infoUuid == null || infoUuid.equals(fwUuid)) {
				// Ignore until we can see if this is for our own endpoint
				return;
			}
			
			String scheme = info.getPropertyString("scheme");
			if(scheme == null) {
				scheme = "http";
			}
			
			String path = info.getPropertyString("path");
			if(path == null) {
				// Not a complete record yet
				return;
			}
			
			int port = info.getPort();
			if(port == -1) {
				switch(scheme) {
					case "http":
						port = 80;
						break;
					case "https":
						port = 443;
						break;
					default:
						LOG.error("Unknown URI scheme advertised {} by framework {} on host {}", 
								scheme, info.getName(), info.getDomain());
				}
			}
			
			String address = info.getInetAddresses()[0].getHostAddress();
			
			String uri = String.format("%s://%s:%d/%s", scheme, address, port, path);
			
			LOG.info("Discovered remote at {}", uri);
			
			namesToUris.put(info.getKey(), uri);
			
			interestManager.remoteAdded(uri);
		}
	}
}
