package com.gentics.mesh.search.index;

import static com.gentics.mesh.search.index.MappingHelper.NAME_KEY;
import static com.gentics.mesh.search.index.MappingHelper.NOT_ANALYZED;
import static com.gentics.mesh.search.index.MappingHelper.STRING;
import static com.gentics.mesh.search.index.MappingHelper.UUID_KEY;
import static com.gentics.mesh.search.index.MappingHelper.fieldType;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import javax.annotation.PostConstruct;

import org.springframework.stereotype.Component;

import com.gentics.mesh.cli.BootstrapInitializer;
import com.gentics.mesh.context.InternalActionContext;
import com.gentics.mesh.core.data.Project;
import com.gentics.mesh.core.data.Tag;
import com.gentics.mesh.core.data.TagFamily;
import com.gentics.mesh.core.data.root.RootVertex;
import com.gentics.mesh.core.data.search.SearchQueueEntry;

import io.vertx.core.json.JsonObject;

@Component
public class TagIndexHandler extends AbstractIndexHandler<Tag> {
	/**
	 * Name of the custom property of SearchQueueEntry containing the project uuid
	 */
	public final static String CUSTOM_PROJECT_UUID = "projectUuid";

	private static TagIndexHandler instance;

	@PostConstruct
	public void setup() {
		instance = this;
	}

	public static TagIndexHandler getInstance() {
		return instance;
	}

	@Override
	protected String getIndex(SearchQueueEntry entry) {
		return getIndexName(entry.getCustomProperty(CUSTOM_PROJECT_UUID));
	}

	@Override
	public Set<String> getIndices() {
		return db.noTrx(() -> {
			List<? extends Project> projects = BootstrapInitializer.getBoot().meshRoot().getProjectRoot().findAll();
			return projects.stream().map(project -> getIndexName(project.getUuid())).collect(Collectors.toSet());
		});
	}

	@Override
	public Set<String> getAffectedIndices(InternalActionContext ac) {
		return db.noTrx(() -> {
			Project project = ac.getProject();
			if (project != null) {
				return Collections.singleton(getIndexName(project.getUuid()));
			} else {
				return getIndices();
			}
		});
	}

	/**
	 * Get the index name for the given project
	 * @param project Uuid
	 * @return index name
	 */
	public String getIndexName(String projectUuid) {
		StringBuilder indexName = new StringBuilder(Tag.TYPE);
		indexName.append("-").append(projectUuid);
		return indexName.toString();
	}

	@Override
	protected String getType() {
		return Tag.TYPE;
	}

	@Override
	public String getKey() {
		return Tag.TYPE;
	}

	@Override
	protected RootVertex<Tag> getRootVertex() {
		return boot.meshRoot().getTagRoot();
	}

	@Override
	protected Map<String, Object> transformToDocumentMap(Tag tag) {
		Map<String, Object> map = new HashMap<>();
		Map<String, String> tagFields = new HashMap<>();
		tagFields.put(NAME_KEY, tag.getName());
		map.put("fields", tagFields);
		addBasicReferences(map, tag);
		addTagFamily(map, tag.getTagFamily());
		addProject(map, tag.getProject());
		return map;
	}

	private void addTagFamily(Map<String, Object> map, TagFamily tagFamily) {
		Map<String, Object> tagFamilyFields = new HashMap<>();
		tagFamilyFields.put(NAME_KEY, tagFamily.getName());
		tagFamilyFields.put(UUID_KEY, tagFamily.getUuid());
		map.put("tagFamily", tagFamilyFields);
	}

	@Override
	protected JsonObject getMapping() {
		JsonObject props = new JsonObject();
		props.put(NAME_KEY, fieldType(STRING, NOT_ANALYZED));
		return props;
	}

}

@@ -859,16 +859,68 @@
 Family;%0A
+import com.gentics.mesh.core.data.root.ProjectRoot;%0A
 import c
@@ -962,16 +962,16 @@
 Vertex;%0A
-
 import c
@@ -1684,39 +1684,27 @@
 %0A%09%09%09
-List%3C? extends 
 Project
-%3E
+Root
  project
 s = 
@@ -1699,17 +1699,20 @@
  project
-s
+Root
  = Boots
@@ -1764,16 +1764,92 @@
 ctRoot()
+;%0A%09%09%09projectRoot.reload();%0A%09%09%09List%3C? extends Project%3E projects = projectRoot
 .findAll
@@ -1855,22 +1855,37 @@
 l();%0A%09%09%09
-return
+Set%3CString%3E indices =
  project
@@ -1972,16 +1972,35 @@
 Set());%0A
+%09%09%09return indices;%0A
 %09%09%7D);%0A%09%7D
@@ -2338,16 +2338,21 @@
 project%0A
+%09 * %0A
 %09 * @par
@@ -2361,16 +2361,31 @@
  project
+%0A%09 *           
  Uuid%0A%09 

Fix test issue