package fr.adrienbrault.idea.symfony2plugin.templating.path;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.util.CachedValue;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
import fr.adrienbrault.idea.symfony2plugin.config.utils.ConfigUtil;
import fr.adrienbrault.idea.symfony2plugin.extension.TwigNamespaceExtension;
import fr.adrienbrault.idea.symfony2plugin.extension.TwigNamespaceExtensionParameter;
import fr.adrienbrault.idea.symfony2plugin.templating.util.TwigUtil;
import fr.adrienbrault.idea.symfony2plugin.util.PsiElementUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.yaml.psi.YAMLFile;
import org.yaml.snakeyaml.Yaml;

import java.util.ArrayList;
import java.util.Collection;

/**
 * Extract Twig path of config.yml
 *
 *  twig:
 *    paths:
 *      "%kernel.root_dir%/../src/vendor/bundle/Resources/views": core
 *      "%kernel.project_dir%/src/vendor/bundle/Resources/views": core
 *      "%kernel.project_dir%/src/vendor/bundle/Resources/views": !core
 *
 * @author Daniel Espendiller <daniel@espendiller.net>
 */
public class ConfigAddPathTwigNamespaces implements TwigNamespaceExtension {
    private static final Key<CachedValue<Collection<TwigPath>>> CACHE = new Key<>("TWIG_CONFIG_ADD_PATH_CACHE");

    @NotNull
    @Override
    public Collection<TwigPath> getNamespaces(@NotNull TwigNamespaceExtensionParameter parameter) {
        Project project = parameter.getProject();

        return CachedValuesManager.getManager(project).getCachedValue(
            project,
            CACHE,
            () -> CachedValueProvider.Result.create(getTwigPaths(project), PsiModificationTracker.MODIFICATION_COUNT),
            false
        );
    }

    @NotNull
    private static Collection<TwigPath> getTwigPaths(@NotNull Project project) {
        Collection<TwigPath> twigPaths = new ArrayList<>();

        // file config files a eg ".../app/..." or "../packages/..."
        Collection<PsiFile> psiFiles = PsiElementUtils.convertVirtualFilesToPsiFiles(
            project,
            ConfigUtil.getConfigurations(project, "twig")
        );

        for (PsiFile psiFile : psiFiles) {
            if (!(psiFile instanceof YAMLFile)) {
                continue;
            }

            for (Pair<String, String> stringStringPair : TwigUtil.getTwigPathFromYamlConfigResolved((YAMLFile) psiFile)) {
                // default path
                String first = stringStringPair.getFirst();
                if(first == null || first.equals("")) {
                    first = TwigUtil.MAIN;
                }

                twigPaths.add(new TwigPath(stringStringPair.getSecond(), first, TwigUtil.NamespaceType.ADD_PATH, true));
            }
        }

        return twigPaths;
    }
}

@@ -201,100 +201,19 @@
 lij.
-openapi.vfs.VirtualFile;%0Aimport com.intellij.psi.PsiFile;%0Aimport com.intellij.psi.PsiManager
+psi.PsiFile
 ;%0Aim
@@ -856,40 +856,37 @@
 le;%0A
+%0A
 import 
-org.yaml.snakeyaml.Yaml;%0A
+java.util.Collection;
 %0Aimp
@@ -899,24 +899,22 @@
 va.util.
-ArrayLis
+HashSe
 t;%0Aimpor
@@ -925,26 +925,33 @@
 va.util.
+stream.
 Collect
-ion
+ors
 ;%0A%0A/**%0A 
@@ -1415,24 +1415,36 @@
 lection%3C
-TwigPath
+Pair%3CString, String%3E
 %3E%3E%3E CACH
@@ -1675,22 +1675,62 @@
         
-return
+Collection%3CPair%3CString, String%3E%3E cachedValue =
  CachedV
@@ -1965,16 +1965,280 @@
       );
+%0A%0A        // TwigPath is not cache able as it right now; we need to build it here%0A        return cachedValue.stream()%0A            .map(p -%3E new TwigPath(p.getFirst(), p.getSecond(), TwigUtil.NamespaceType.ADD_PATH, true))%0A            .collect(Collectors.toList());
 %0A    %7D%0A%0A
@@ -2276,32 +2276,44 @@
  Collection%3C
-TwigPath
+Pair%3CString, String%3E
 %3E getTwigPat
@@ -2366,42 +2366,60 @@
 ion%3C
-TwigPath%3E twigPaths = new ArrayLis
+Pair%3CString, String%3E%3E twigPathNamespace = new HashSe
 t%3C%3E(
@@ -3163,26 +3163,33 @@
 Path
-s.add(new TwigPath
+Namespace.add(Pair.create
 (str
@@ -3224,47 +3224,8 @@
 irst
-, TwigUtil.NamespaceType.ADD_PATH, true
 ));%0A
@@ -3272,17 +3272,25 @@
 twigPath
-s
+Namespace
 ;%0A    %7D%0A

fix TwigPath caching issue on extracting config path from yaml file #1358 #1506