/*
 * Copyright 2001-2012 Remi Vankeisbelck
 *
 * 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 woko.idea;

import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiFile;
import com.intellij.psi.search.GlobalSearchScope;
import net.sourceforge.jfacets.FacetDescriptor;
import org.jetbrains.annotations.NotNull;
import woko.tooling.cli.Runner;
import woko.tooling.utils.AppUtils;
import woko.tooling.utils.Logger;
import woko.tooling.utils.PomHelper;

import java.io.File;
import java.io.StringWriter;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class WokoProjectComponent implements ProjectComponent {

    private final Project project;
    private JavaPsiFacade psiFacade;
    private GlobalSearchScope projectScope;

    private List<FacetDescriptor> facetDescriptors = Collections.emptyList();
    private Map<String,Long> refreshStamps = Collections.emptyMap();

    public WokoProjectComponent(Project project) {
        this.project = project;
    }

    public void initComponent() {
    }

    public void disposeComponent() {
    }

    @NotNull
    public String getComponentName() {
        return "WokoProjectComponent";
    }

    public void projectOpened() {
        psiFacade = JavaPsiFacade.getInstance(project);
        projectScope = GlobalSearchScope.projectScope(project);
    }

    public void projectClosed() {
        // called when project is being closed
    }

    public boolean openClassInEditor(String fqcn) {
        if (fqcn==null) {
            return false;
        }
        PsiClass c = getPsiClass(fqcn);
        if (c!=null) {
            c.getContainingFile().navigate(true);
            return true;
        }
        return false;
    }

    public void refresh() {
        // invoke runner to grab the facets in the project
        VirtualFile baseDir = project.getBaseDir();
        if (baseDir==null) {
            facetDescriptors = Collections.emptyList();
        } else {
            File projectRootDir = new File(baseDir.getPath());
            StringWriter sw = new StringWriter();
            Logger logger = new Logger(sw);
            Runner runner = new Runner(logger, projectRootDir);
            try {
                Object result = runner.invokeCommand("list", "facets", "customClassLoader");
                if (result instanceof List) {
                    facetDescriptors = (List<FacetDescriptor>)result;
                }
            } catch(Exception e) {
                facetDescriptors = Collections.emptyList();
                // TODO handle errors
            }
        }
        // init refresh stamps
        Map<String,Long> newStamps = new HashMap<String, Long>();
        for (FacetDescriptor fd : facetDescriptors) {
            String fqcn = fd.getFacetClass().getName();
            PsiFile f = getPsiFile(fqcn);
            if (f!=null) {
                newStamps.put(fqcn, f.getModificationStamp());
            }
        }
        refreshStamps = newStamps;
    }

    public List<FacetDescriptor> getFacetDescriptors() {
        return facetDescriptors;
    }

    public boolean push(String url, String username, String password) {
        PomHelper pomHelper = AppUtils.getPomHelper(new File(project.getBaseDir().getPath()));
        List<String> facetSources = null;
        StringWriter sw = new StringWriter();
        Logger logger = new Logger(sw);
        AppUtils.pushFacetSources(pomHelper, logger, url, username, password, facetSources);
        return true;
    }

    public PsiClass getPsiClass(String fqcn) {
        return psiFacade.findClass(fqcn, projectScope);
    }

    public PsiFile getPsiFile(String fqcn) {
        PsiClass pc = getPsiClass(fqcn);
        if (pc!=null) {
            return pc.getContainingFile();
        }
        return null;
    }

    public void openPushDialog() {
        PushFacetsDialogWrapper w = new PushFacetsDialogWrapper(project);
        w.setTitle("Push facets...");
        w.pack();
        w.show();
    }


    public Long getLastRefreshStamp(FacetDescriptor fd) {
        return refreshStamps.get(fd.getFacetClass().getName());
    }
}


@@ -754,27 +754,17 @@
 api.vfs.
-VirtualFile
+*
 ;%0Aimport
@@ -3505,24 +3505,152 @@
 .getName();%0A
+            // keep old stamp if any%0A            Long oldStamp = refreshStamps.get(fqcn);%0A            if (oldStamp==null) %7B%0A    
             
@@ -3671,32 +3671,36 @@
 tPsiFile(fqcn);%0A
+    
             if (
@@ -3726,16 +3726,20 @@
         
+    
 newStamp
@@ -3773,24 +3773,110 @@
 onStamp());%0A
+                %7D%0A            %7D else %7B%0A                newStamps.put(fqcn, oldStamp);%0A
             

refresh stamps