/*
 * Copyright 2011-2021 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.codesystem;

import static com.b2international.snowowl.test.commons.rest.RestExtensions.givenAuthenticatedRequest;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import com.b2international.commons.json.Json;
import com.b2international.snowowl.core.ResourceURI;
import com.b2international.snowowl.core.api.IBranchPath;
import com.b2international.snowowl.core.branch.Branch;
import com.b2international.snowowl.core.repository.RepositoryRequests;
import com.b2international.snowowl.snomed.common.SnomedTerminologyComponentConstants;
import com.b2international.snowowl.test.commons.ApiTestConstants;
import com.b2international.snowowl.test.commons.Services;

import io.restassured.http.ContentType;
import io.restassured.response.ValidatableResponse;

/**
 * Common requests for working with Code Systems (only SNOMED CT is supported).
 * 
 * @since 4.7
 */
public abstract class CodeSystemRestRequests {
	
	public static ValidatableResponse createCodeSystem(String codeSystemId) {
		String branchPath = RepositoryRequests.branching().prepareCreate()
			.setParent(Branch.MAIN_PATH)
			.setName(codeSystemId)
			.build(SnomedTerminologyComponentConstants.TOOLING_ID)
			.execute(Services.bus())
			.getSync(1, TimeUnit.MINUTES);
		return createCodeSystem(null, branchPath, codeSystemId);
	}
	
	public static ValidatableResponse createCodeSystem(IBranchPath branchPath, String codeSystemId) {
		return createCodeSystem(branchPath.getPath(), codeSystemId);
	}
	
	public static ValidatableResponse createCodeSystem(String branchPath, String codeSystemId) {
		return createCodeSystem(null, branchPath, codeSystemId);
	}

	public static ValidatableResponse createCodeSystem(ResourceURI extensionOf, String codeSystemId) {
		return createCodeSystem(extensionOf, null, codeSystemId);
	}
	
	private static ValidatableResponse createCodeSystem(ResourceURI extensionOf, String branchPath, String codeSystemId) {
		Json requestBody = Json.object(
			"id", codeSystemId,
			"title", codeSystemId,
			"url", getCodeSystemUrl(codeSystemId),
			"description", "<div>Markdown supported</div>",
			"toolingId", SnomedTerminologyComponentConstants.TOOLING_ID,
			"oid", "oid_" + codeSystemId,
			"language", "ENG",
			"extensionOf", extensionOf,
			"branchPath", branchPath,
			"owner", "https://b2i.sg"
		);
				
		return givenAuthenticatedRequest(ApiTestConstants.CODESYSTEMS_API)
				.contentType(ContentType.JSON)
				.body(requestBody)
				.post()
				.then();
	}

	public static String getCodeSystemUrl(String codeSystemId) {
		return SnomedTerminologyComponentConstants.SNOMED_URI_SCT + "/" + codeSystemId;
	}

	public static ValidatableResponse getCodeSystem(String id) {
		return givenAuthenticatedRequest(ApiTestConstants.CODESYSTEMS_API)
				.get("/{id}", id)
				.then();
	}

	public static ValidatableResponse updateCodeSystem(String id, Map<?, ?> requestBody) {
		return givenAuthenticatedRequest(ApiTestConstants.CODESYSTEMS_API)
				.contentType(ContentType.JSON)
				.body(requestBody)
				.put("/{id}", id)
				.then();
	}
	
	public static ValidatableResponse deleteCodeSystem(String codeSystemId) {
		return givenAuthenticatedRequest(ApiTestConstants.CODESYSTEMS_API)
				.delete("/{id}", codeSystemId)
				.then();

	}
	
	public static ValidatableResponse upgrade(ResourceURI upgradeOf, ResourceURI extensionOf) {
		return givenAuthenticatedRequest("/upgrade")
				.contentType(ContentType.JSON)
				.body(Map.of(
					"extensionOf", extensionOf.toString(),
					"upgradeOf", upgradeOf.toString()
				))
				.post()
				.then();
	}
	
	public static ValidatableResponse search(String id, String expand) {
		return givenAuthenticatedRequest(ApiTestConstants.CODESYSTEMS_API)
				.contentType(ContentType.JSON)
				.body(Map.of(
						"id", Set.of(id),
						"expand", expand
					))
				.post("/search")
				.then();
	}

	private CodeSystemRestRequests() {
		throw new UnsupportedOperationException("This class is not supposed to be instantiated.");
	}

}

@@ -2485,16 +2485,422 @@
 );%0A%09%7D%0A%09%0A
+%09public static ValidatableResponse createCodeSystem(ResourceURI extensionOf, String branchPath, String codeSystemId) %7B%0A%09%09return createCodeSystem(extensionOf, branchPath, codeSystemId, Map.of());%0A%09%7D%0A%09%0A%09public static ValidatableResponse createCodeSystem(ResourceURI extensionOf, String codeSystemId,  Map%3CString, Object%3E settings) %7B%0A%09%09return createCodeSystem(extensionOf, null, codeSystemId, settings);%0A%09%7D%0A%09%0A
 %09private
@@ -3003,24 +3003,55 @@
 codeSystemId
+,  Map%3CString, Object%3E settings
 ) %7B%0A%09%09Json r
@@ -3397,16 +3397,16 @@
 chPath,%0A
-
 %09%09%09%22owne
@@ -3425,16 +3425,41 @@
 /b2i.sg%22
+,%0A%09%09%09%22settings%22, settings
 %0A%09%09);%0A%09%09

add settings parameter to createCodeSystem