package org.zalando.intellij.swagger.file;

import com.intellij.json.JsonLanguage;
import com.intellij.lang.Language;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import org.apache.commons.io.FilenameUtils;
import org.jetbrains.yaml.YAMLLanguage;
import org.zalando.intellij.swagger.traversal.path.PathFinder;

public class FileDetector {

    private static final String SWAGGER_KEY = "swagger";
    private static final String OPEN_API_KEY = "openapi";

    public boolean isMainSwaggerJsonFile(final PsiFile psiFile) {
        return hasJsonRootKey(psiFile, String.format("$.%s", SWAGGER_KEY));
    }

    public boolean isMainSwaggerYamlFile(final PsiFile psiFile) {
        return hasYamlRootKey(psiFile, String.format("$.%s", SWAGGER_KEY));
    }

    public boolean isMainOpenApiJsonFile(final PsiFile psiFile) {
        return hasJsonRootKey(psiFile, String.format("$.%s", OPEN_API_KEY));
    }

    public boolean isMainOpenApiYamlFile(final PsiFile psiFile) {
        return hasYamlRootKey(psiFile, String.format("$.%s", OPEN_API_KEY));
    }

    private boolean hasYamlRootKey(final PsiFile psiFile, final String lookupKey) {
        final Language language = psiFile.getLanguage();

        return YAMLLanguage.INSTANCE.is(language) && new PathFinder().findByPathFrom(lookupKey, psiFile).isPresent();
    }

    private boolean hasJsonRootKey(final PsiFile psiFile, final String lookupKey) {
        final Language language = psiFile.getLanguage();

        return JsonLanguage.INSTANCE.is(language) && new PathFinder().findByPathFrom(lookupKey, psiFile).isPresent();
    }

    public boolean isMainSwaggerFile(final PsiFile file) {
        return isMainSwaggerJsonFile(file) || isMainSwaggerYamlFile(file);
    }

    public boolean isMainOpenApiFile(final PsiFile file) {
        return isMainOpenApiJsonFile(file) || isMainOpenApiYamlFile(file);
    }

    public boolean isSwaggerContentCompatible(VirtualFile file) {
        return FilenameUtils.isExtension(file.getName(),
                new String[]{FileConstants.JSON_FILE_EXTENSION,
                        FileConstants.YAML_FILE_EXTENSION,
                        FileConstants.YML_FILE_EXTENSION});
    }
}

@@ -152,24 +152,60 @@
 irtualFile;%0A
+import com.intellij.psi.PsiElement;%0A
 import com.i
@@ -459,16 +459,71 @@
 agger%22;%0A
+    private static final String SWAGGER_VERSION = %222%22;%0A
     priv
@@ -571,16 +571,72 @@
 penapi%22;
+%0A    private static final String OPEN_API_VERSION = %223%22;
 %0A%0A    pu
@@ -760,32 +760,49 @@
 s%22, SWAGGER_KEY)
+, SWAGGER_VERSION
 );%0A    %7D%0A%0A    pu
@@ -930,24 +930,41 @@
 SWAGGER_KEY)
+, SWAGGER_VERSION
 );%0A    %7D%0A%0A  
@@ -1093,32 +1093,50 @@
 %22, OPEN_API_KEY)
+, OPEN_API_VERSION
 );%0A    %7D%0A%0A    pu
@@ -1269,16 +1269,34 @@
 API_KEY)
+, OPEN_API_VERSION
 );%0A    %7D
@@ -1369,32 +1369,60 @@
 String lookupKey
+, final String lookupVersion
 ) %7B%0A        fina
@@ -1462,33 +1462,32 @@
 Language();%0A
-%0A
         
 return YAMLL
@@ -1474,23 +1474,20 @@
         
-return 
+if(!
 YAMLLang
@@ -1516,62 +1516,189 @@
 age)
- && new PathFinder().findByPathFrom(lookupKey, psiFile
+)%7B%0A            return false;%0A        %7D%0A        return new PathFinder().findByPathFrom(lookupKey, psiFile)%0A                .filter(psiElement -%3E hasVersion(psiElement, lookupVersion)
 ).is
@@ -1795,16 +1795,44 @@
 ookupKey
+, final String lookupVersion
 ) %7B%0A    
@@ -1884,25 +1884,24 @@
 uage();%0A
-%0A
         
 return J
@@ -1892,23 +1892,20 @@
         
-return 
+if(!
 JsonLang
@@ -1934,74 +1934,374 @@
 age)
- && new PathFinder().findByPathFrom(lookupKey, psiFile).isPresent(
+)%7B%0A            return false;%0A        %7D%0A        return new PathFinder().findByPathFrom(lookupKey, psiFile)%0A                .filter(psiElement -%3E hasVersion(psiElement, lookupVersion)).isPresent();%0A    %7D%0A%0A    private boolean hasVersion(final PsiElement psiElement, final String lookupVersion) %7B%0A        return psiElement.getLastChild().getText().contains(lookupVersion
 );%0A 

check that version is defined before being considered a valid swagger or openapi file