package org.kohsuke.github;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * Utility class for creating and retrieving webhooks; removes duplication between GHOrganization and GHRepository
 * functionality
 */
class GHHooks {
    static abstract class Context {
        private final GitHub root;

        private Context(GitHub root) {
          this.root = root;
        }

        public List<GHHook> getHooks() throws IOException {
            List<GHHook> list = new ArrayList<GHHook>(Arrays.asList(
                root.retrieve().to(collection(), collectionClass())));
            for (GHHook h : list)
              wrap(h);
            return list;
        }

        public GHHook getHook(int id) throws IOException {
            GHHook hook = root.retrieve().to(collection() + "/" + id, clazz());
            return wrap(hook);
        }

        public GHHook createHook(String name, Map<String, String> config, Collection<GHEvent> events, boolean active) throws IOException {
            List<String> ea = null;
            if (events!=null) {
              ea = new ArrayList<String>();
              for (GHEvent e : events)
                ea.add(e.name().toLowerCase(Locale.ENGLISH));
            }

            GHHook hook = new Requester(root)
                .with("name", name)
                .with("active", active)
                ._with("config", config)
                ._with("events", ea)
                .to(collection(), clazz());

            return wrap(hook);
        }

        abstract String collection();

        abstract Class<? extends GHHook[]> collectionClass();

        abstract Class<? extends GHHook> clazz();

        abstract GHHook wrap(GHHook hook);
    }

    private static class RepoContext extends Context {
        private final GHRepository repository;
        private final GHUser owner;

        private RepoContext(GHRepository repository, GHUser owner) {
            super(repository.root);
            this.repository = repository;
            this.owner = owner;
        }

        @Override
        String collection() {
            return String.format("/repos/%s/%s/hooks", owner.getLogin(), repository.getName());
        }

        @Override
        Class<? extends GHHook[]> collectionClass() {
            return GHRepoHook[].class;
        }

        @Override
        Class<? extends GHHook> clazz() {
            return GHRepoHook.class;
        }

        @Override
        GHHook wrap(GHHook hook) {
            return ((GHRepoHook)hook).wrap(repository);
        }
    }

    private static class OrgContext extends Context {
        private final GHOrganization organization;

        private OrgContext(GHOrganization organization) {
            super(organization.root);
            this.organization = organization;
        }

        @Override
        String collection() {
            return String.format("/orgs/%s/hooks", organization.getLogin());
        }

        @Override
        Class<? extends GHHook[]> collectionClass() {
            return GHOrgHook[].class;
        }

        @Override
        Class<? extends GHHook> clazz() {
            return GHOrgHook.class;
        }

        @Override
        GHHook wrap(GHHook hook) {
            return ((GHOrgHook)hook).wrap(organization);
        }
    }

      static Context repoContext(GHRepository repository, GHUser owner) {
          return new RepoContext(repository, owner);
      }

      static Context orgContext(GHOrganization organization) {
          return new OrgContext(organization);
      }
}

@@ -581,84 +581,43 @@
     
-    List%3CGHHook%3E list = new ArrayList%3CGHH
+%09%0A            GHHook %5B%5D h
 ook
-%3E(
 Array
-s.asList(%0A              
  
+=
  roo
@@ -645,17 +645,16 @@
 ction(),
- 
 collecti
@@ -663,16 +663,152 @@
 Class())
+;  // jdk/eclipse bug requires this to be on separate line%0A            List%3CGHHook%3E list = new ArrayList%3CGHHook%3E(Arrays.asList(hookArray
 ));%0A    

Fix compilation errror: The constructor ArrayList<GHHook>(List<capture#1-of ? extends GHHook[]>) is undefined