/*
 * Copyright 2000-2012 JetBrains s.r.o.
 *
 * 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.intellij.ide.favoritesTreeView;

import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.usageView.UsageInfo;
import com.intellij.usages.Usage;
import com.intellij.usages.UsageInfo2UsageAdapter;
import com.intellij.usages.UsageView;
import com.intellij.usages.impl.NullUsage;
import com.intellij.usages.rules.UsageInFile;
import com.intellij.usages.rules.UsageInFiles;
import com.intellij.util.ProxyComparator;
import com.intellij.util.SmartList;
import com.intellij.util.containers.Convertor;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: Irina.Chernushina
 * Date: 6/6/12
 * Time: 6:51 PM
 */
public class UsageFavoriteNodeProvider extends FavoriteNodeProvider {
  private final static Map<String, TreeSet<WorkingSetSerializable>> ourSerializables =
    new HashMap<String, TreeSet<WorkingSetSerializable>>();
  private final static Comparator<VirtualFile> VIRTUAL_FILE_COMPARATOR =
    new ProxyComparator<String, VirtualFile>(new Convertor<VirtualFile, String>() {
      @Override
      public String convert(VirtualFile o) {
        return o.getPath();
      }
    });
  private static final Logger LOG = Logger.getInstance("#com.intellij.ide.favoritesTreeView.UsageFavoriteNodeProvider");

  static {
    final TreeSet<WorkingSetSerializable> usageSet = createSet();
    final UsageSerializable serializable = new UsageSerializable();
    ourSerializables.put(serializable.getId(), usageSet);
    usageSet.add(serializable);

    final TreeSet<WorkingSetSerializable> fileSet = createSet();
    final FileSerializable fileSerializable = new FileSerializable();
    ourSerializables.put(fileSerializable.getId(), fileSet);
    fileSet.add(fileSerializable);

    final TreeSet<WorkingSetSerializable> noteSet = createSet();
    final NoteSerializable noteSerializable = new NoteSerializable();
    ourSerializables.put(noteSerializable.getId(), noteSet);
    noteSet.add(noteSerializable);
  }

  private static TreeSet<WorkingSetSerializable> createSet() {
    return new TreeSet<WorkingSetSerializable>(new Comparator<WorkingSetSerializable>() {
      @Override
      public int compare(WorkingSetSerializable o1, WorkingSetSerializable o2) {
        assert o1.getId().equals(o1.getId());
        return Comparing.compare(o1.getVersion(), o2.getVersion());
      }
    });
  }

  @Override
  public Collection<AbstractTreeNode> getFavoriteNodes(DataContext context, ViewSettings viewSettings) {
    final Project project = CommonDataKeys.PROJECT.getData(context);
    if (project == null) {
      return null;
    }
    final Usage[] usages = UsageView.USAGES_KEY.getData(context);
    if (usages != null) {

      final List<AbstractTreeNode> result = new SmartList<AbstractTreeNode>();
      final MultiMap<VirtualFile, Usage> map = new MultiMap<VirtualFile, Usage>();
      final List<Usage> nonMapped = new ArrayList<Usage>();
      for (Usage usage : usages) {
        if (usage instanceof UsageInFile) {
          map.putValue(((UsageInFile)usage).getFile(), usage);
        }
        else if (usage instanceof UsageInFiles) {
          final VirtualFile[] files = ((UsageInFiles)usage).getFiles();
          for (VirtualFile file : files) {
            map.putValue(file, usage);
          }
        }
        else {
          nonMapped.add(usage);
        }
      }

      final TreeSet<VirtualFile> keys = new TreeSet<VirtualFile>(VIRTUAL_FILE_COMPARATOR);
      keys.addAll(map.keySet());
      for (VirtualFile key : keys) {
        final FileGroupingProjectNode grouping = new FileGroupingProjectNode(project, new File(key.getPath()), viewSettings);
        result.add(grouping);
        final Collection<Usage> subUsages = map.get(key);
        for (Usage usage : subUsages) {
          if (usage instanceof UsageInfo2UsageAdapter) {
            final UsageProjectTreeNode node =
              new UsageProjectTreeNode(project, ((UsageInfo2UsageAdapter)usage).getUsageInfo(), viewSettings);
            grouping.addChild(node);
          }
          else if (NullUsage.INSTANCE.equals(usage)) {
            continue;
          }
          else {
            grouping.addChild(new NoteProjectNode(project, new NoteNode(usage.getPresentation().getPlainText(), true), viewSettings));
          }
        }
      }
      for (Usage usage : nonMapped) {
        if (usage instanceof UsageInfo2UsageAdapter) {
          final UsageProjectTreeNode node =
            new UsageProjectTreeNode(project, ((UsageInfo2UsageAdapter)usage).getUsageInfo(), viewSettings);
          result.add(node);
        }
        else if (NullUsage.INSTANCE.equals(usage)) {
          continue;
        }
        else {
          result.add(new NoteProjectNode(project, new NoteNode(usage.getPresentation().getPlainText(), true), viewSettings));
        }
      }

      return result;
    }
    return null;
  }

  @Override
  public AbstractTreeNode createNode(Project project, Object element, ViewSettings viewSettings) {
    if (element instanceof UsageInfo) {
      return new UsageProjectTreeNode(project, (UsageInfo)element, viewSettings);
    }
    else if (element instanceof InvalidUsageNoteNode) {
      return new InvalidUsageNoteProjectNode(project, (InvalidUsageNoteNode)element, viewSettings);
    }
    else if (element instanceof NoteNode) {
      return new NoteProjectNode(project, (NoteNode)element, viewSettings);
    }
    else if (element instanceof File) {
      return new FileGroupingProjectNode(project, (File)element, viewSettings);
    }
    return super.createNode(project, element, viewSettings);
  }

  @Override
  public PsiElement getPsiElement(Object element) {
    if (element instanceof UsageInfo) {
      return ((UsageInfo)element).getElement();
    }
    return super.getPsiElement(element);
  }

  @Override
  public boolean elementContainsFile(Object element, VirtualFile vFile) {
    return false;
  }

  @Override
  public int getElementWeight(Object element, boolean isSortByType) {
    return 0;
  }

  @Override
  public String getElementLocation(Object element) {
    if (element instanceof UsageInfo) {
      final PsiElement psiElement = ((UsageInfo)element).getElement();
      final PsiFile file = psiElement.getContainingFile();
      /*if (parent != null) {
        return ClassPresentationUtil.getNameForClass(parent, true);
      }*/
      return file.getPresentation().getPresentableText();//+-      // todo do smthg for invalid usage
    }
    else if (element instanceof File) {
      return ((File)element).getParent();
    }
    return null;
  }

  @Override
  public boolean isInvalidElement(Object element) {
    /*if (element instanceof UsageInfo) {
      return ((UsageInfo)element).getElement().isValid();
    } else if (element instanceof InvalidUsageNoteNode) {
      return true;
    } */
    return false;
  }

  @NotNull
  @Override
  public String getFavoriteTypeId() {
    return "usage";
  }

  @Override
  public String getElementUrl(Object element) {
    //if (element instanceof UsageInfo) {
    final TreeSet<WorkingSetSerializable> serializables = ourSerializables.get(element.getClass().getName());
    if (serializables != null && !serializables.isEmpty()) {
      final WorkingSetSerializable last = serializables.last();
      //final ByteArrayOutputStream baos = new ByteArrayOutputStream();
      try {
        //final ObjectOutputStream os = new ObjectOutputStream(baos);
        final StringBuilder sb = new StringBuilder();
        sb.append(last.getId());
        sb.append(' ');
        sb.append("" + last.getVersion());
        sb.append(' ');

        //os.writeUTF(last.getId());
        //os.writeInt(last.getVersion());
        last.serializeMe(element, sb);
        //os.close();
        //final byte[] bytes = baos.toByteArray();
        return sb.toString();
        //return new String(bytes, 4, bytes.length - 4);
      }
      catch (IOException e) {
        LOG.info(e);
        return null;
      }
    }
    //}
    return null;
  }

  @Override
  public String getElementModuleName(Object element) {
    if (element instanceof UsageInfo) {
      Module module = ModuleUtil.findModuleForPsiElement(((UsageInfo)element).getElement());
      return module != null ? module.getName() : null;
    }
    return null;
  }

  @Override
  public Object[] createPathFromUrl(Project project, String url, String moduleName) {
    try {
      //final byte[] bytes = url.getBytes(CharsetToolkit.UTF8_CHARSET);
      /*final byte[] wrapped = new byte[bytes.length + 4];
      final ByteArrayOutputStream bas = new ByteArrayOutputStream();
      final ObjectOutputStream oos = new ObjectOutputStream(bas);
      oos.close();
      final byte[] header = bas.toByteArray();
      System.arraycopy(header, 0, wrapped, 0, 4);
      System.arraycopy(bytes, 0, wrapped, 0, bytes.length);*/

      //ObjectInputStream is = new ObjectInputStream(new ByteArrayInputStream(bytes));
      final List<String> parts = StringUtil.split(url, " ", true);
      if (parts.size() < 3) return null;

      final String id = parts.get(0);
      final TreeSet<WorkingSetSerializable> set = ourSerializables.get(id);
      if (set != null && !set.isEmpty()) {
        final int version = Integer.parseInt(parts.get(1));
        final String cut = StringUtil.join(parts.subList(2, parts.size()), " ");
        for (Iterator<WorkingSetSerializable> iterator = set.descendingIterator(); iterator.hasNext(); ) {
          WorkingSetSerializable serializable = iterator.next();
          if (serializable.getVersion() == version) {
            return readWithSerializable(project, url, cut, serializable);
          }
        }
        readWithSerializable(project, url, cut, set.last());
      }
    }
    catch (IOException e) {
      LOG.info(e);
    }
    return null;
  }

  private Object[] readWithSerializable(Project project, String url, String is, WorkingSetSerializable serializable)
    throws IOException {
    Object obj = serializable.deserializeMe(project, is);
    if (obj == null) {
      obj = serializable.deserializeMeInvalid(project, is);
    }
    return obj == null ? null : new Object[]{obj};
    /*Object obj = serializable.deserializeMe(project, is);
    if (obj == null) {
      is.close();
      is = new ObjectInputStream(new ByteArrayInputStream(url.getBytes(CharsetToolkit.UTF8_CHARSET)));
      is.readUTF();
      is.readInt();
      obj = serializable.deserializeMeInvalid(project, is);
    }
    if (obj != null) {
      return new Object[]{obj};
    } else {
      return null;
    }*/
  }
}
