package org.hanuna.gitalk.refs;

import org.hanuna.gitalk.commitmodel.Commit;
import org.hanuna.gitalk.commitmodel.Hash;
import org.hanuna.gitalk.common.ReadOnlyList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author erokhins
 */
public class RefsModel {
    public static RefsModel existedCommitRefs(List<Ref> allRefs, List<Commit> commits) {
        Set<Hash> refCommits = new HashSet<Hash>();
        for (Ref ref : allRefs) {
            refCommits.add(ref.getCommitHash());
        }
        Set<Hash> existedCommitsRefs = new HashSet<Hash>();
        for (Commit commit : commits) {
            if (refCommits.contains(commit.hash())) {
                existedCommitsRefs.add(commit.hash());
            }
        }

        List<Ref> existedRef = new ArrayList<Ref>();
        for (Ref ref : allRefs) {
            if (existedCommitsRefs.contains(ref.getCommitHash())) {
                existedRef.add(ref);
            }
        }
        return new RefsModel(existedRef);
    }

    private final List<Ref> allRefs;
    private final Set<Hash> trackedHash = new HashSet<Hash>();
    private final List<Ref> localBranches = new ArrayList<Ref>();
    private final List<Ref> remoteBranches = new ArrayList<Ref>();

    public RefsModel(List<Ref> allRefs) {
        this.allRefs = allRefs;
        for (Ref ref : allRefs) {
            trackedHash.add(ref.getCommitHash());
            if (ref.getType() == Ref.Type.LOCAL_BRANCH) {
                localBranches.add(ref);
            }
            if (ref.getType() == Ref.Type.REMOTE_BRANCH) {
                remoteBranches.add(ref);
            }
        }
    }

    @Nullable
    public Ref refToCommit(@NotNull Hash hash) {
        if (trackedHash.contains(hash)) {
            for (Ref ref : allRefs) {
                if (ref.getCommitHash().equals(hash)) {
                    return ref;
                }
            }
        }
        return null;
    }

    public ReadOnlyList<Ref> localBranches() {
        return ReadOnlyList.newReadOnlyList(localBranches);
    }

    public ReadOnlyList<Ref> remoteBranches() {
        return ReadOnlyList.newReadOnlyList(remoteBranches);
    }

}

@@ -1794,21 +1794,36 @@
 ublic Re
-f
+adOnlyList%3CRef%3E
  ref
+s
 ToCommit
@@ -1841,24 +1841,71 @@
 ash hash) %7B%0A
+        List%3CRef%3E refs = new ArrayList%3CRef%3E();%0A
         if (
@@ -2054,16 +2054,19 @@
   re
-turn 
+fs.add(
 ref
+)
 ;%0A  
@@ -2124,12 +2124,42 @@
 urn 
-null
+ReadOnlyList.newReadOnlyList(refs)
 ;%0A  

fix returned type RefsModel.refToCommit()