/*
 * Copyright 2011-2017 B2i Healthcare Pte Ltd, http://b2i.sg
 * 
 * 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 com.b2international.snowowl.test.commons;

import static com.google.common.base.Preconditions.checkNotNull;

import java.io.File;

import org.junit.rules.ExternalResource;

import com.b2international.commons.ConsoleProgressMonitor;
import com.b2international.commons.platform.PlatformUtil;
import com.b2international.snowowl.core.ApplicationContext;
import com.b2international.snowowl.core.api.IBranchPath;
import com.b2international.snowowl.core.branch.Branch;
import com.b2international.snowowl.datastore.BranchPathUtils;
import com.b2international.snowowl.datastore.CodeSystems;
import com.b2international.snowowl.datastore.request.RepositoryRequests;
import com.b2international.snowowl.eventbus.IEventBus;
import com.b2international.snowowl.snomed.common.ContentSubType;
import com.b2international.snowowl.snomed.common.SnomedTerminologyComponentConstants;
import com.b2international.snowowl.snomed.core.domain.Rf2ReleaseType;
import com.b2international.snowowl.snomed.datastore.SnomedDatastoreActivator;
import com.b2international.snowowl.snomed.importer.rf2.util.ImportUtil;
import com.b2international.snowowl.terminologyregistry.core.request.CodeSystemRequests;

/**
 * JUnit test rule to import SNOMED CT content during automated tests.
 * 
 * @since 3.6
 */
public class SnomedContentRule extends ExternalResource {

	private final File importArchive;
	private final Rf2ReleaseType contentType;
	private final String codeSystemShortName;
	private final String codeSystemBranchPath;

	public SnomedContentRule(final String codeSystemShortName, final String branchPath, final String importArchivePath, final Rf2ReleaseType contentType) {
		this.codeSystemShortName = checkNotNull(codeSystemShortName, "codeSystem");
		this.codeSystemBranchPath = checkNotNull(branchPath, "branchPath");
		this.contentType = checkNotNull(contentType, "contentType");
		this.importArchive = new File(PlatformUtil.toAbsolutePathBundleEntry(SnomedContentRule.class, importArchivePath));
	}

	@Override
	protected void before() throws Throwable {
		createBranch();
		createCodeSystemIfNotExist();
		new ImportUtil().doImport(codeSystemShortName, "info@b2international.com", getContentSubType(contentType), codeSystemBranchPath, importArchive, true, new ConsoleProgressMonitor());
	}
	
	private static ContentSubType getContentSubType(Rf2ReleaseType contentType) {
		switch (contentType) {
		case DELTA: return ContentSubType.DELTA;
		case SNAPSHOT: return ContentSubType.SNAPSHOT;
		case FULL: return ContentSubType.FULL;
		}
		return null;
	}

	private void createBranch() {
		if (!IBranchPath.MAIN_BRANCH.equals(codeSystemBranchPath)) {
			final IBranchPath csPath = BranchPathUtils.createPath(codeSystemBranchPath);
			RepositoryRequests.branching().prepareCreate()
				.setParent(csPath.getParentPath())
				.setName(csPath.lastSegment())
				.build(SnomedDatastoreActivator.REPOSITORY_UUID)
				.execute(getBus())
				.getSync()
				.path();
		}
	}

	private void createCodeSystemIfNotExist() {
		if (!SnomedTerminologyComponentConstants.SNOMED_SHORT_NAME.equals(codeSystemShortName)) {
			final IEventBus eventBus = getBus();
			
			CodeSystems codeSystems = CodeSystemRequests.prepareSearchCodeSystem()
					.setLimit(0)
					.filterById(codeSystemShortName)
					.build(SnomedDatastoreActivator.REPOSITORY_UUID)
					.execute(eventBus)
					.getSync();
			
			if (codeSystems.getTotal() < 1) {
				CodeSystemRequests.prepareNewCodeSystem()
					.setBranchPath(codeSystemBranchPath)
					.setCitation("citation")
					.setExtensionOf(SnomedTerminologyComponentConstants.SNOMED_SHORT_NAME)
					.setIconPath("iconPath")
					.setLanguage("language")
					.setLink("organizationLink")
					.setName("Extension " + codeSystemShortName)
					.setOid("oid:"+codeSystemShortName)
					.setRepositoryUuid(SnomedDatastoreActivator.REPOSITORY_UUID)
					.setShortName(codeSystemShortName)
					.setTerminologyId(SnomedTerminologyComponentConstants.TERMINOLOGY_ID)
					.build(SnomedDatastoreActivator.REPOSITORY_UUID, Branch.MAIN_PATH, "info@b2international.com", String.format("Create code system %s", codeSystemShortName))
					.execute(eventBus)
					.getSync();
			}
		}
	}
	
	private static IEventBus getBus() {
		return ApplicationContext.getServiceForClass(IEventBus.class);
	}
}

@@ -2274,16 +2274,302 @@
 Type) %7B%0A
+%09%09this(codeSystemShortName, branchPath, SnomedContentRule.class, importArchivePath, contentType);%0A%09%7D%0A%09%0A%09public SnomedContentRule(final String codeSystemShortName, final String branchPath, final Class%3C?%3E relativeClass, final String importArchivePath, final Rf2ReleaseType contentType) %7B%0A
 %09%09this.c
@@ -2634,24 +2634,24 @@
 deSystem%22);%0A
-
 %09%09this.codeS
@@ -2842,35 +2842,25 @@
 leEntry(
-SnomedContentRule.c
+relativeC
 lass, im

Support for loading from different bundles.