package org.kohsuke.github;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

/**
 * A team in GitHub organization.
 * 
 * @author Kohsuke Kawaguchi
 */
public class GHTeam {
    private String name,permission;
    private int id;
    private GHOrganization organization; // populated by GET /user/teams where Teams+Orgs are returned together

    protected /*final*/ GHOrganization org;

    /*package*/ GHTeam wrapUp(GHOrganization owner) {
        this.org = owner;
        return this;
    }

    /*package*/ GHTeam wrapUp(GitHub root) { // auto-wrapUp when organization is known from GET /user/teams
      this.organization.wrapUp(root);
      return wrapUp(organization);
    }

    /*package*/ static GHTeam[] wrapUp(GHTeam[] teams, GHOrganization owner) {
        for (GHTeam t : teams) {
            t.wrapUp(owner);
        }
        return teams;
    }

    public String getName() {
        return name;
    }

    public String getPermission() {
        return permission;
    }

    public int getId() {
        return id;
    }

    /**
     * Retrieves the current members.
     */
    public Set<GHUser> getMembers() throws IOException {
        return new HashSet<GHUser>(Arrays.asList(GHUser.wrap(org.root.retrieve().to(api("/members"), GHUser[].class), org.root)));
    }

    /**
     * Checks if this team has the specified user as a member.
     */
    public boolean hasMember(GHUser user) {
        try {
            org.root.retrieve().to("/teams/" + id + "/members/"  + user.getLogin());
            return true;
        } catch (IOException ignore) {
            return false;
        }
    }

    public Map<String,GHRepository> getRepositories() throws IOException {
        Map<String,GHRepository> m = new TreeMap<String, GHRepository>();
        for (GHRepository r : listRepositories()) {
            m.put(r.getName(), r);
        }
        return m;
    }

    public PagedIterable<GHRepository> listRepositories() {
        return new PagedIterable<GHRepository>() {
            public PagedIterator<GHRepository> iterator() {
                return new PagedIterator<GHRepository>(org.root.retrieve().asIterator(api("/repos"), GHRepository[].class)) {
                    @Override
                    protected void wrapUp(GHRepository[] page) {
                        for (GHRepository r : page)
                            r.wrap(org.root);
                    }
                };
            }
        };
    }

    /**
     * Adds a member to the team.
     *
     * The user will be invited to the organization if required.
     *
     * @since 1.59
     */
    public void add(GHUser u) throws IOException {
        org.root.retrieve().method("PUT").to(api("/memberships/" + u.getLogin()), null);
    }

    /**
     * Removes a member to the team.
     */
    public void remove(GHUser u) throws IOException {
        org.root.retrieve().method("DELETE").to(api("/members/" + u.getLogin()), null);
    }

    public void add(GHRepository r) throws IOException {
        org.root.retrieve().method("PUT").to(api("/repos/" + r.getOwnerName() + '/' + r.getName()), null);
    }

    public void remove(GHRepository r) throws IOException {
        org.root.retrieve().method("DELETE").to(api("/repos/" + r.getOwnerName() + '/' + r.getName()), null);
    }

    private String api(String tail) {
        return "/teams/"+id+tail;
    }

    public GHOrganization getOrganization() {
      return org;
    }
}

@@ -92,16 +92,105 @@
 va.util.
+Collections;%0Aimport java.util.HashSet;%0Aimport java.util.Iterator;%0Aimport java.util.Linked
 HashSet;
@@ -259,16 +259,42 @@
 TreeMap;
+%0Aimport java.util.TreeSet;
 %0A%0A/**%0A *
@@ -1249,36 +1249,30 @@
  id;%0A    %7D%0A%0A
-    /**%0A    
+%09/**%0A%09
  * Retrieves
@@ -1293,28 +1293,22 @@
 embers.%0A
-     */%0A    
+%09 */%0A%09
 public S
@@ -1356,69 +1356,101 @@
 n %7B%0A
-        return new HashSet%3CGHUser%3E(Arrays.asList(GHUser.wrap(
+%0A%09%09Set%3CGHUser%3E members = new LinkedHashSet%3CGHUser%3E();%0A%09%09%0A%09%09Iterator%3CGHUser%5B%5D%3E pageIterator = 
 org.
@@ -1465,18 +1465,26 @@
 rieve().
+asItera
 to
+r
 (api(%22/m
@@ -1492,17 +1492,21 @@
 mbers%22),
- 
+%0A%09%09%09%09
 GHUser%5B%5D
@@ -1516,27 +1516,300 @@
 ass)
-, org.root)));%0A    
+;%0A%09%09while (pageIterator != null && pageIterator.hasNext()) %7B%0A%09%09%09GHUser%5B%5D users = pageIterator.next();%0A%09%09%09if (users != null) %7B%0A%09%09%09%09GHUser.wrap(users, org.root); %0A%09%09%09%09for (GHUser user : users) %7B%09%09%09%09%09%0A%09%09%09%09%09members.add(user);%09%09%09%09%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D%0A%09%09%0A%09%09return Collections.unmodifiableSet(members);%0A%09
 %7D%0A%0A 

fix #145 GHTeam.getMembers() does not page properly