/**
 * 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.apache.aries.cdi.container.internal.container;

import static org.apache.aries.cdi.container.internal.util.Filters.asFilter;

import java.util.Iterator;
import java.util.List;
import java.util.SortedSet;
import java.util.concurrent.ConcurrentSkipListSet;

import javax.enterprise.inject.spi.Extension;

import org.apache.aries.cdi.container.internal.container.Op.Mode;
import org.apache.aries.cdi.container.internal.container.Op.Type;
import org.apache.aries.cdi.container.internal.model.ExtendedExtensionDTO;
import org.apache.aries.cdi.container.internal.model.ExtendedExtensionTemplateDTO;
import org.apache.aries.cdi.container.internal.util.Conversions;
import org.apache.aries.cdi.container.internal.util.Perms;
import org.apache.aries.cdi.container.internal.util.SRs;
import org.apache.aries.cdi.container.internal.util.Syncro;
import org.apache.aries.cdi.container.internal.util.Throw;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
import org.osgi.framework.ServiceReference;
import org.osgi.service.cdi.runtime.dto.ExtensionDTO;
import org.osgi.service.cdi.runtime.dto.template.ExtensionTemplateDTO;
import org.osgi.service.log.Logger;
import org.osgi.util.promise.Promise;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;

public class ExtensionPhase extends Phase {

	public ExtensionPhase(ContainerState containerState, Phase next) {
		super(containerState, next);
		_log = containerState.containerLogs().getLogger(getClass());
	}

	@Override
	public boolean close() {
		try (Syncro open = syncro.open()) {
			if (extensionTemplates().isEmpty()) {
				next.map(
					next -> {
						submit(next.closeOp(), next::close).onFailure(
							f -> {
								_log.error(l -> l.error("CCR Error in extension CLOSE on {}", bundle(), f));

								error(f);
							}
						);

						return true;
					}
				).orElse(true);
			}

			if (_extensionTracker != null) {
				_extensionTracker.close();

				_extensionTracker = null;
			}

			return true;
		}
	}

	@Override
	public Op closeOp() {
		return Op.of(Mode.CLOSE, Type.EXTENSION, containerState.id());
	}

	@Override
	public boolean open() {
		try (Syncro open = syncro.open()) {
			if (containerState.bundleContext() == null) {
				// this bundle was already removed
				return false;
			}

			_extensionTracker = new ServiceTracker<>(
				containerState.bundleContext(), createExtensionFilter(), new ExtensionPhaseCustomizer());

			_extensionTracker.open();

			if (extensionTemplates().isEmpty()) {
				next.map(
					next -> {
						submit(next.openOp(), next::open).onFailure(
							f -> {
								_log.error(l -> l.error("CCR Error in extension OPEN on {}", bundle(), f));

								error(f);
							}
						);

						return true;
					}
				).orElse(true);
			}

			return true;
		}
	}

	@Override
	public Op openOp() {
		return Op.of(Mode.OPEN, Type.EXTENSION, containerState.id());
	}

	Filter createExtensionFilter() {
		final List<ExtensionTemplateDTO> templates = extensionTemplates();

		StringBuilder sb = new StringBuilder("(&(objectClass=" + Extension.class.getName() + ")");

		sb.append("(|");

		for (ExtensionTemplateDTO tmpl : templates) {
			sb.append(tmpl.serviceFilter);
		}

		sb.append("(aries.cdi.extension.mode=implicit))");

		sb.append(")");

		return asFilter(sb.toString());
	}

	List<ExtensionTemplateDTO> extensionTemplates() {
		return containerState.containerDTO().template.extensions;
	}

	List<ExtensionDTO> snapshots() {
		return containerState.containerDTO().extensions;
	}


	private ServiceTracker<Extension, ExtendedExtensionDTO> _extensionTracker;
	private final Logger _log;
	private final SortedSet<ExtendedExtensionDTO> _references = new ConcurrentSkipListSet<>(
		(e1, e2) -> e1.serviceReference.compareTo(e2.serviceReference)
	);

	private final Filter implicitFilter = asFilter("(aries.cdi.extension.mode=implicit)");

	private class ExtensionPhaseCustomizer implements ServiceTrackerCustomizer<Extension, ExtendedExtensionDTO> {

		@Override
		public ExtendedExtensionDTO addingService(ServiceReference<Extension> reference) {
			if (!Perms.hasExtensionServicePermission(containerState.bundleContext())) {
				return null;
			}

			ExtendedExtensionTemplateDTO template = extensionTemplates().stream().map(
				t -> (ExtendedExtensionTemplateDTO)t
			).filter(
				t -> t.filter.match(reference)
			).findFirst().orElseGet(() -> {
				if (implicitFilter.match(reference)) {
					ExtendedExtensionTemplateDTO implicitTemplate = new ExtendedExtensionTemplateDTO();
					implicitTemplate.filter = asFilter("(&(aries.cdi.extension.mode=implicit)(service.id=%s))", reference.getProperty(Constants.SERVICE_ID));
					implicitTemplate.serviceFilter = implicitTemplate.filter.toString();
					return implicitTemplate;
				}
				return null;
			});

			ExtendedExtensionDTO snapshot = snapshots().stream().map(
				s -> (ExtendedExtensionDTO)s
			).filter(
				s -> s.template == template
			).findFirst().orElse(null);

			if (snapshot != null) {
				if (reference.compareTo(snapshot.serviceReference) <= 0) {
					return null;
				}

				if (snapshots().remove(snapshot)) {
					_references.add(snapshot);
					snapshot.extension = null;
					containerState.bundleContext().ungetService(snapshot.serviceReference);
				}
			}

			ExtendedExtensionDTO extensionDTO = new ExtendedExtensionDTO();

			BundleContext bc = containerState.bundleContext();

			extensionDTO.extension = bc.getServiceObjects(reference);
			extensionDTO.service = SRs.from(reference);
			extensionDTO.serviceReference = reference;
			extensionDTO.template = template;

			snapshots().add(extensionDTO);
			containerState.incrementChangeCount();

			next.ifPresent(
				next -> submit(next.closeOp(), next::close).then(
					s -> {
						if (extensionTemplates().stream().allMatch(tmpl -> snapshots().stream().anyMatch(ext -> ext.template == tmpl))) {
							return submit(next.openOp(), next::open).onFailure(
								f -> {
									_log.error(l -> l.error("CCR Error in extension open TRACKING {} on {}", reference, bundle(), f));

									error(f);
								}
							);
						}

						return s;
					},
					f -> {
						_log.error(l -> l.error("CCR Error extension close TRACKING {} on {}", reference, bundle(), f.getFailure()));

						error(f.getFailure());
					}
				)
			);

			return extensionDTO;
		}

		@Override
		public void modifiedService(ServiceReference<Extension> reference, ExtendedExtensionDTO extentionDTO) {
			removedService(reference, extentionDTO);
			addingService(reference);
		}

		@Override
		public void removedService(ServiceReference<Extension> reference, final ExtendedExtensionDTO extensionDTO) {
			_log.debug(l -> l.debug("CCR Departing extension {} on {}", Conversions.convert(extensionDTO).to(ExtensionDTO.class), bundle()));

			containerState.bundleContext().ungetService(reference);

			if (!snapshots().removeIf(snap ->
					((ExtendedExtensionDTO)snap).serviceReference.equals(reference))) {
				return;
			}

			for (Iterator<ExtendedExtensionDTO> itr = _references.iterator();itr.hasNext();) {
				ExtendedExtensionDTO entry = itr.next();
				if (((ExtendedExtensionTemplateDTO)extensionDTO.template).filter.match(entry.serviceReference)) {
					entry.extension = containerState.bundleContext().getServiceObjects(entry.serviceReference);
					itr.remove();
					snapshots().add(entry);
					break;
				}
			}

			containerState.incrementChangeCount();

			next.ifPresent(
				next -> {
					Promise<Boolean> result = submit(next.closeOp(), next::close).then(
						s -> {
							if (extensionTemplates().stream().allMatch(tmpl -> snapshots().stream().anyMatch(ext -> ext.template == tmpl))) {
								return submit(next.openOp(), next::open).onFailure(
									f -> {
										_log.error(l -> l.error("CCR Error in extension open {} on {}", reference, bundle(), f));

										error(f);
									}
								);
							}

							return s;
						},
						f -> {
							_log.error(l -> l.error("CCR Error in extension close {} on {}", reference, bundle(), f.getFailure()));

							error(f.getFailure());
						}
					);

					try {
						result.getValue();
					}
					catch (Exception e) {
						Throw.exception(e);
					}
				}
			);
		}

	}

}
