package io.cattle.platform.storage.api.filter;

import io.cattle.platform.archaius.util.ArchaiusUtil;
import io.cattle.platform.core.constants.InstanceConstants;
import io.cattle.platform.core.model.Instance;
import io.cattle.platform.storage.service.StorageService;
import io.cattle.platform.util.type.CollectionUtils;
import io.github.ibuildthecloud.gdapi.exception.ValidationErrorException;
import io.github.ibuildthecloud.gdapi.factory.SchemaFactory;
import io.github.ibuildthecloud.gdapi.request.ApiRequest;
import io.github.ibuildthecloud.gdapi.request.resource.AbstractResourceManagerFilter;
import io.github.ibuildthecloud.gdapi.request.resource.ResourceManager;
import io.github.ibuildthecloud.gdapi.validation.ValidationErrorCodes;
import io.cattle.platform.docker.client.DockerImage;

import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import org.apache.commons.lang3.StringUtils;

import com.netflix.config.DynamicStringProperty;

public class ExternalTemplateInstanceFilter extends AbstractResourceManagerFilter {

    SchemaFactory schemaFactory;
    @Inject
    StorageService storageService;

    public static final DynamicStringProperty DEFAULT_REGISTRY = ArchaiusUtil.getString("registry.default");
    public static final DynamicStringProperty WHITELIST_REGISTRIES = ArchaiusUtil.getString("registry.whitelist");
    @Override
    public Object create(String type, ApiRequest request, ResourceManager next) {
        Map<String, Object> data = CollectionUtils.toMap(request.getRequestObject());
        Object imageUuid = data.get(InstanceConstants.FIELD_IMAGE_UUID);

        if (imageUuid != null) {
            String image = imageUuid.toString();
            String fullImageName = getImageUuid(image, storageService);
            if (!StringUtils.equals(image, fullImageName)) {
                data.put(InstanceConstants.FIELD_IMAGE_UUID, fullImageName);
                request.setRequestObject(data);
            }
        }
        return super.create(type, request, next);
    }

    public static String getImageUuid(String image, StorageService storageService) {
        validateImageUuid(image);
        DockerImage dockerImage = DockerImage.parse(image);
        if (dockerImage == null) {
            throw new ValidationErrorException(ValidationErrorCodes.INVALID_REFERENCE, InstanceConstants.FIELD_IMAGE_UUID);
        }

        String fullImageName = dockerImage.getFullName();
        String server = dockerImage.getServer();
        if (!fullImageName.startsWith(server)) {
            String defaultRegistry = DEFAULT_REGISTRY.get();
            if (!StringUtils.isBlank(defaultRegistry) && !StringUtils.isEmpty(defaultRegistry)) {
                fullImageName = defaultRegistry + "/" + fullImageName;
            }
        }

        if (image.startsWith(DockerImage.KIND_PREFIX)) {
            fullImageName = DockerImage.KIND_PREFIX + fullImageName;
        }
        if (!storageService.isValidUUID(fullImageName.toString())) {
            throw new ValidationErrorException(ValidationErrorCodes.INVALID_REFERENCE, InstanceConstants.FIELD_IMAGE_UUID);
        }

        return fullImageName;
    }

    protected static void validateImageUuid(String image) {
        DockerImage dockerImage = DockerImage.parse(image);
        if (dockerImage == null) {
            return;
        }

        String server = dockerImage.getServer();
        String qualifiedName = dockerImage.getQualifiedName();
        String whitelist = WHITELIST_REGISTRIES.get();
        String defaultRegistry = DEFAULT_REGISTRY.get();
        String userProvidedRegistry = dockerImage.getServer();

        if (!qualifiedName.startsWith(server)) {
            if(!StringUtils.isBlank(defaultRegistry)) {
                userProvidedRegistry = defaultRegistry;
            }
        }


        String[] whitelistRegistries;
        if (specified(whitelist)) {
            whitelistRegistries = WHITELIST_REGISTRIES.get().split(",");
            if (!StringUtils.isEmpty(userProvidedRegistry) && !StringUtils.isBlank(userProvidedRegistry)) {
                if (!contains(whitelistRegistries, userProvidedRegistry)) {
                    throw new ValidationErrorException(ValidationErrorCodes.INVALID_OPTION, InstanceConstants.FIELD_IMAGE_UUID);
                }
            }
            else {
                if (!StringUtils.isEmpty(defaultRegistry) && !StringUtils.isBlank(defaultRegistry)) {
                    if (!contains(whitelistRegistries, defaultRegistry)) {
                        throw new ValidationErrorException(ValidationErrorCodes.INVALID_OPTION, InstanceConstants.FIELD_IMAGE_UUID);
                    }
                }
            }
        }
    }

    public static boolean contains(String[] arr, String target) {
        for(String str: arr){
            if(str.equals(target))
                return true;
        }
        return false;
    }

    public static boolean specified(String registry) {
        if (registry != null && !registry.isEmpty() && !registry.trim().isEmpty()) {
            return true;
        }
        return false;
    }

    @Override
    public String[] getTypes() {
        List<String> types = schemaFactory.getSchemaNames(Instance.class);
        return types.toArray(new String[types.size()]);
    }

    public SchemaFactory getSchemaFactory() {
        return schemaFactory;
    }

    @Inject
    public void setSchemaFactory(SchemaFactory schemaFactory) {
        this.schemaFactory = schemaFactory;
    }
}

@@ -910,16 +910,69 @@
 Utils;%0A%0A
+import com.netflix.config.DynamicStringListProperty;%0A
 import c
@@ -1317,32 +1317,36 @@
 al DynamicString
+List
 Property WHITELI
@@ -1369,38 +1369,36 @@
 ArchaiusUtil.get
-String
+List
 (%22registry.white
@@ -2496,38 +2496,40 @@
 %0A        String 
-server
+registry
  = dockerImage.g
@@ -2570,38 +2570,40 @@
 Name.startsWith(
-server
+registry
 )) %7B%0A           
@@ -2659,32 +2659,159 @@
 %0A            if 
+(image.contains(registry)) %7B%0A                fullImageName = registry + %22/%22 + fullImageName;%0A            %7D%0A            else if 
 (!StringUtils.is
@@ -3551,22 +3551,24 @@
  String 
-server
+registry
  = docke
@@ -3599,77 +3599,20 @@
     
-String qualifiedName = dockerImage.getQualifiedName();%0A        
+List%3C
 String
+%3E
  whi
@@ -3617,16 +3617,26 @@
 hitelist
+Registries
  = WHITE
@@ -3796,39 +3796,31 @@
 f (!
-qualifiedName.startsWith(server
+image.contains(registry
 )) %7B
@@ -3966,25 +3966,20 @@
         
-String%5B%5D 
+if (
 whitelis
@@ -3993,118 +3993,22 @@
 ries
-;%0A        if (specified(whitelist)) %7B%0A            whitelistRegistries = WHITELIST_REGISTRIES.get().split(%22,%22);
+.size() %3E 0) %7B
 %0A   
@@ -4129,33 +4129,24 @@
        if (!
-contains(
 whitelistReg
@@ -4152,18 +4152,26 @@
 gistries
-, 
+.contains(
 userProv
@@ -4494,25 +4494,16 @@
    if (!
-contains(
 whitelis
@@ -4513,18 +4513,26 @@
 gistries
-, 
+.contains(
 defaultR
@@ -4751,411 +4751,8 @@
  %7D%0A%0A
-    public static boolean contains(String%5B%5D arr, String target) %7B%0A        for(String str: arr)%7B%0A            if(str.equals(target))%0A                return true;%0A        %7D%0A        return false;%0A    %7D%0A%0A    public static boolean specified(String registry) %7B%0A        if (registry != null && !registry.isEmpty() && !registry.trim().isEmpty()) %7B%0A            return true;%0A        %7D%0A        return false;%0A    %7D%0A%0A
     

Change condition to use default registry