/*
 * Copyright 2000-2013 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 git4idea.repo;

import com.intellij.dvcs.repo.Repository;
import com.intellij.openapi.util.Comparing;
import git4idea.GitLocalBranch;
import git4idea.GitRemoteBranch;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;

/**
 * @author Kirill Likhodedov
 */
public class GitRepoInfo {

  @Nullable private final GitLocalBranch myCurrentBranch;
  @Nullable private final String myCurrentRevision;
  @NotNull private final Repository.State myState;
  @NotNull private final Collection<GitRemote> myRemotes;
  @NotNull private final Collection<GitLocalBranch> myLocalBranches;
  @NotNull private final Collection<GitRemoteBranch> myRemoteBranches;
  @NotNull private final Collection<GitBranchTrackInfo> myBranchTrackInfos;

  public GitRepoInfo(@Nullable GitLocalBranch currentBranch, @Nullable String currentRevision, @NotNull Repository.State state,
                     @NotNull Collection<GitRemote> remotes, @NotNull Collection<GitLocalBranch> localBranches,
                     @NotNull Collection<GitRemoteBranch> remoteBranches, @NotNull Collection<GitBranchTrackInfo> branchTrackInfos) {
    myCurrentBranch = currentBranch;
    myCurrentRevision = currentRevision;
    myState = state;
    myRemotes = remotes;
    myLocalBranches = localBranches;
    myRemoteBranches = remoteBranches;
    myBranchTrackInfos = branchTrackInfos;
  }

  @Nullable
  public GitLocalBranch getCurrentBranch() {
    return myCurrentBranch;
  }

  @NotNull
  public Collection<GitRemote> getRemotes() {
    return myRemotes;
  }

  @NotNull
  public Collection<GitLocalBranch> getLocalBranches() {
    return myLocalBranches;
  }

  @NotNull
  public Collection<GitRemoteBranch> getRemoteBranches() {
    return myRemoteBranches;
  }

  @NotNull
  public Collection<GitBranchTrackInfo> getBranchTrackInfos() {
    return myBranchTrackInfos;
  }

  @Nullable
  public String getCurrentRevision() {
    return myCurrentRevision;
  }

  @NotNull
  public Repository.State getState() {
    return myState;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    GitRepoInfo info = (GitRepoInfo)o;

    if (myState != info.myState) return false;
    if (myCurrentRevision != null ? !myCurrentRevision.equals(info.myCurrentRevision) : info.myCurrentRevision != null) return false;
    if (myCurrentBranch != null ? !myCurrentBranch.equals(info.myCurrentBranch) : info.myCurrentBranch != null) return false;
    if (!Comparing.haveEqualElements(myRemotes, info.myRemotes)) return false;
    if (!Comparing.haveEqualElements(myBranchTrackInfos, info.myBranchTrackInfos)) return false;
    if (!Comparing.haveEqualElements(myLocalBranches, info.myLocalBranches)) return false;
    if (!Comparing.haveEqualElements(myRemoteBranches, info.myRemoteBranches)) return false;

    return true;
  }

  @Override
  public int hashCode() {
    int result = myCurrentBranch != null ? myCurrentBranch.hashCode() : 0;
    result = 31 * result + (myCurrentRevision != null ? myCurrentRevision.hashCode() : 0);
    result = 31 * result + myState.hashCode();
    result = 31 * result + hashCodeForCollectionComparison(myRemotes);
    result = 31 * result + hashCodeForCollectionComparison(myLocalBranches);
    result = 31 * result + hashCodeForCollectionComparison(myRemoteBranches);
    result = 31 * result + hashCodeForCollectionComparison(myBranchTrackInfos);
    return result;
  }

  private static <T> int hashCodeForCollectionComparison(@NotNull Collection<T> collection) {
    int i = 0;
    for (T element : collection) {
      i += element.hashCode();
    }
    return i;
  }

  @Override
  public String toString() {
    return String.format("GitRepoInfo{current=%s, remotes=%s, localBranches=%s, remoteBranches=%s, trackInfos=%s}",
                         myCurrentBranch, myRemotes, myLocalBranches, myRemoteBranches, myBranchTrackInfos);
  }
}

@@ -664,52 +664,8 @@
 ry;%0A
-import com.intellij.openapi.util.Comparing;%0A
 impo
@@ -3119,36 +3119,8 @@
 f (!
-Comparing.haveEqualElements(
 myRe
@@ -3124,18 +3124,24 @@
 yRemotes
-, 
+.equals(
 info.myR
@@ -3176,36 +3176,8 @@
 f (!
-Comparing.haveEqualElements(
 myBr
@@ -3190,18 +3190,24 @@
 ackInfos
-, 
+.equals(
 info.myB
@@ -3251,36 +3251,8 @@
 f (!
-Comparing.haveEqualElements(
 myLo
@@ -3258,26 +3258,32 @@
 ocalBranches
-, 
+.equals(
 info.myLocal
@@ -3320,36 +3320,8 @@
 f (!
-Comparing.haveEqualElements(
 myRe
@@ -3332,18 +3332,24 @@
 Branches
-, 
+.equals(
 info.myR
@@ -3683,111 +3683,57 @@
 t + 
-hashCodeForCollectionComparison(myRemotes);%0A    result = 31 * result + hashCodeForCollectionComparison(
+myRemotes.hashCode();%0A    result = 31 * result + 
 myLo
@@ -3735,32 +3735,42 @@
  myLocalBranches
+.hashCode(
 );%0A    result = 
@@ -3787,40 +3787,8 @@
 t + 
-hashCodeForCollectionComparison(
 myRe
@@ -3799,16 +3799,26 @@
 Branches
+.hashCode(
 );%0A    r
@@ -3843,247 +3843,26 @@
 t + 
-hashCodeForCollectionComparison(myBranchTrackInfos);%0A    return result;%0A  %7D%0A%0A  private static %3CT%3E int hashCodeForCollectionComparison(@NotNull Collection%3CT%3E collection) %7B%0A    int i = 0;%0A    for (T element : collection) %7B%0A      i += element
+myBranchTrackInfos
 .has
@@ -3874,14 +3874,8 @@
 ();%0A
-    %7D%0A
     
@@ -3881,17 +3881,22 @@
  return 
-i
+result
 ;%0A  %7D%0A%0A 

Revert "[git] Fix equals & hashcode for GitRepoInfo"