/*
 * Copyright 2022 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.core.request.resource;

import com.b2international.snowowl.core.ResourceURI;
import com.b2international.snowowl.core.ServiceProvider;
import com.b2international.snowowl.core.domain.RepositoryContext;
import com.b2international.snowowl.core.request.GetResourceRequest;
import com.b2international.snowowl.core.request.ResourceRequests;
import com.b2international.snowowl.core.request.RevisionIndexReadRequestTimestampProvider;
import com.b2international.snowowl.core.request.SearchResourceRequestBuilder;
import com.b2international.snowowl.core.version.Version;
import com.google.common.base.Strings;

/**
 * @since 8.7
 * 
 * @param <SB>
 * @param <SR>
 * @param <R>
 */
public abstract class BaseGetResourceRequest<SB extends SearchResourceRequestBuilder<SB, RepositoryContext, SR>, SR, R> 
		extends GetResourceRequest<SB, RepositoryContext, SR, R>
		implements RevisionIndexReadRequestTimestampProvider {

	private static final long serialVersionUID = 1L;
	
	private final ResourceURI resourceUri;
	
	public BaseGetResourceRequest(ResourceURI resourceUri) {
		super(resourceUri.getResourceId());
		this.resourceUri = resourceUri;
	}
	
	@Override
	public final Long getReadTimestamp(ServiceProvider context) {
		if (!Strings.isNullOrEmpty(resourceUri.getTimestampPart())) {
			return Long.parseLong(resourceUri.getTimestampPart().substring(1));
		} else if (!resourceUri.isHead() && !resourceUri.isNext()) {
			return ResourceRequests.prepareSearchVersion()
					.one()
					.filterByResource(resourceUri.withoutPath())
					.filterByVersionId(resourceUri.getPath())
					.buildAsync()
					.execute(context)
					.first()
					.map(Version::getCreatedAt)
					.orElse(null);
		}
		return null;
	}

}

@@ -676,16 +676,83 @@
 ource;%0A%0A
+import com.b2international.commons.exceptions.BadRequestException;%0A
 import c
@@ -967,34 +967,17 @@
 request.
-GetResourceRequest
+*
 ;%0Aimport
@@ -1022,112 +1022,40 @@
 est.
-ResourceRequests;%0Aimport com.b2international.snowowl.core.request.RevisionIndexReadRequestTimestampProvi
+version.VersionSearchRequestBuil
 der;
@@ -1099,44 +1099,23 @@
 ore.
-request.SearchResourceRequestBuilder
+version.Version
 ;%0Aim
@@ -1159,32 +1159,40 @@
 .version.Version
+Document
 ;%0Aimport com.goo
@@ -2029,22 +2029,59 @@
 )) %7B%0A%09%09%09
-return
+VersionSearchRequestBuilder versionSearch =
  Resourc
@@ -2113,17 +2113,16 @@
 rsion()%0A
-%09
 %09%09%09%09.one
@@ -2124,25 +2124,24 @@
 %09.one()%0A%09%09%09%09
-%09
 .filterByRes
@@ -2172,22 +2172,358 @@
 tPath())
+;
 %0A%09%09%09
+%0A%09
 %09%09
+if (resourceUri.isLatest()) %7B%0A%09%09%09%09// fetch the latest resource version if LATEST is specified in the URI%0A%09%09%09%09versionSearch.sortBy(SearchResourceRequest.Sort.fieldDesc(VersionDocument.Fields.EFFECTIVE_TIME));%0A%09%09%09%7D else %7B%0A%09%09%09%09// try to fetch the path as exact version if not the special LATEST is specified in the URI%0A%09%09%09%09versionSearch
 .filterB
@@ -2555,22 +2555,238 @@
 tPath())
+;
 %0A%09%09%09
-%09%09
+%7D%0A%09%09%09%0A%09%09%09// determine the final branch path, if based on the version search we find a version, then use that, otherwise use the defined path as relative branch of the code system working branch%0A%09%09%09return versionSearch
 .buildAs
@@ -2791,17 +2791,16 @@
 Async()%0A
-%09
 %09%09%09%09.exe
@@ -2813,17 +2813,16 @@
 ontext)%0A
-%09
 %09%09%09%09.fir
@@ -2830,17 +2830,16 @@
 t()%0A%09%09%09%09
-%09
 .map(Ver
@@ -2866,21 +2866,361 @@
 %09%09%09%09
-%09
 .orElse
-(null
+Get(() -%3E %7B%0A%09%09%09%09%09// ignore if accessing the LATEST versioned state, but there is no version present%0A%09%09%09%09%09if (resourceUri.isLatest()) %7B%0A%09%09%09%09%09%09return null;%0A%09%09%09%09%09%7D else %7B%0A%09%09%09%09%09%09throw new BadRequestException(%22Only version paths and timestamp fragments are supported when accessing a resource via an URI. Got: %25s%22, resourceUri.getPath());%0A%09%09%09%09%09%7D%0A%09%09%09%09%7D
 );%0A%09

support accessing the version denoted by the LATEST keyword