// Copyright (C) 2013 The Android Open Source Project
//
// 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.google.gerrit.server.project;

import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.gerrit.extensions.common.ActionInfo;
import com.google.gerrit.extensions.common.WebLinkInfo;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.extensions.restapi.RestView;
import com.google.gerrit.extensions.webui.UiAction;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.WebLinks;
import com.google.gerrit.server.extensions.webui.UiActions;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.inject.Inject;
import com.google.inject.util.Providers;

import dk.brics.automaton.RegExp;
import dk.brics.automaton.RunAutomaton;

import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.kohsuke.args4j.Option;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class ListBranches implements RestReadView<ProjectResource> {
  private final GitRepositoryManager repoManager;
  private final DynamicMap<RestView<BranchResource>> branchViews;
  private final WebLinks webLinks;

  @Option(name = "--limit", aliases = {"-n"}, metaVar = "CNT", usage = "maximum number of branches to list")
  private int limit;

  @Option(name = "--start", aliases = {"-s"}, metaVar = "CNT", usage = "number of branches to skip")
  private int start;

  @Option(name = "--match", aliases = {"-m"}, metaVar = "MATCH", usage = "match branches substring")
  private String matchSubstring;

  @Option(name = "--regex", aliases = {"-r"}, metaVar = "REGEX", usage = "match branches regex")
  private String matchRegex;

  @Inject
  public ListBranches(GitRepositoryManager repoManager,
      DynamicMap<RestView<BranchResource>> branchViews,
      WebLinks webLinks) {
    this.repoManager = repoManager;
    this.branchViews = branchViews;
    this.webLinks = webLinks;
  }

  @Override
  public List<BranchInfo> apply(ProjectResource rsrc)
      throws ResourceNotFoundException, IOException, BadRequestException {
    List<BranchInfo> branches = Lists.newArrayList();

    BranchInfo headBranch = null;
    BranchInfo configBranch = null;
    final Set<String> targets = Sets.newHashSet();

    final Repository db;
    try {
      db = repoManager.openRepository(rsrc.getNameKey());
    } catch (RepositoryNotFoundException noGitRepository) {
      throw new ResourceNotFoundException();
    }

    try {
      List<Ref> refs =
          new ArrayList<>(db.getRefDatabase().getRefs(Constants.R_HEADS)
              .values());

        try {
          Ref head = db.getRef(Constants.HEAD);
          if (head != null) {
            refs.add(head);
          }
        } catch (IOException e) {
          // Ignore the failure reading HEAD.
        }
        try {
          Ref config = db.getRef(RefNames.REFS_CONFIG);
          if (config != null) {
            refs.add(config);
          }
        } catch (IOException e) {
          // Ignore the failure reading refs/meta/config.
        }

      for (Ref ref : refs) {
        if (ref.isSymbolic()) {
          targets.add(ref.getTarget().getName());
        }
      }

      for (Ref ref : refs) {
        if (ref.isSymbolic()) {
          // A symbolic reference to another branch, instead of
          // showing the resolved value, show the name it references.
          //
          String target = ref.getTarget().getName();
          RefControl targetRefControl = rsrc.getControl().controlForRef(target);
          if (!targetRefControl.isVisible()) {
            continue;
          }
          if (target.startsWith(Constants.R_HEADS)) {
            target = target.substring(Constants.R_HEADS.length());
          }

          BranchInfo b = new BranchInfo(ref.getName(), target, false);

          if (Constants.HEAD.equals(ref.getName())) {
            headBranch = b;
          } else {
            b.setCanDelete(targetRefControl.canDelete());
            branches.add(b);
          }
          continue;
        }

        final RefControl refControl = rsrc.getControl().controlForRef(ref.getName());
        if (refControl.isVisible()) {
          if (RefNames.REFS_CONFIG.equals(ref.getName())) {
            configBranch = createBranchInfo(ref, refControl, targets);
          } else {
            branches.add(createBranchInfo(ref, refControl, targets));
          }
        }
      }
    } finally {
      db.close();
    }
    Collections.sort(branches, new Comparator<BranchInfo>() {
      @Override
      public int compare(final BranchInfo a, final BranchInfo b) {
        return a.ref.compareTo(b.ref);
      }
    });
    if (configBranch != null) {
      branches.add(0, configBranch);
    }
    if (headBranch != null) {
      branches.add(0, headBranch);
    }

    List<BranchInfo> filteredBranches;
    if ((matchSubstring != null && !matchSubstring.isEmpty())
        || (matchRegex != null && !matchRegex.isEmpty())) {
      filteredBranches = filterBranches(branches);
    } else {
      filteredBranches = branches;
    }
    if (!filteredBranches.isEmpty()) {
      int end = filteredBranches.size();
      if (limit > 0 && start + limit < end) {
        end = start + limit;
      }
      if (start <= end) {
        filteredBranches = filteredBranches.subList(start, end);
      } else {
        filteredBranches = Collections.emptyList();
      }
    }
    return filteredBranches;
  }

  private List<BranchInfo> filterBranches(List<BranchInfo> branches)
      throws BadRequestException {
    if (matchSubstring != null) {
      return Lists.newArrayList(Iterables.filter(branches,
          new Predicate<BranchInfo>() {
            @Override
            public boolean apply(BranchInfo in) {
              if (!in.ref.startsWith(Constants.R_HEADS)){
                return in.ref.toLowerCase(Locale.US).contains(
                    matchSubstring.toLowerCase(Locale.US));
              } else {
                return in.ref.substring(Constants.R_HEADS.length())
                    .toLowerCase(Locale.US)
                    .contains(matchSubstring.toLowerCase(Locale.US));
              }
            }
          }));
    } else if (matchRegex != null) {
      if (matchRegex.startsWith("^")) {
        matchRegex = matchRegex.substring(1);
        if (matchRegex.endsWith("$") && !matchRegex.endsWith("\\$")) {
          matchRegex = matchRegex.substring(0, matchRegex.length() - 1);
        }
      }
      if (matchRegex.equals(".*")) {
        return branches;
      }
      try {
        final RunAutomaton a =
            new RunAutomaton(new RegExp(matchRegex).toAutomaton());
        return Lists.newArrayList(Iterables.filter(
            branches, new Predicate<BranchInfo>() {
              @Override
              public boolean apply(BranchInfo in) {
                if (!in.ref.startsWith(Constants.R_HEADS)){
                  return a.run(in.ref);
                } else {
                  return a.run(in.ref.substring(Constants.R_HEADS.length()));
                }
              }
            }));
      } catch (IllegalArgumentException e) {
        throw new BadRequestException(e.getMessage());
      }
    }
    return branches;
  }

  private BranchInfo createBranchInfo(Ref ref, RefControl refControl,
      Set<String> targets) {
    BranchInfo info = new BranchInfo(ref.getName(),
        ref.getObjectId() != null ? ref.getObjectId().name() : null,
        !targets.contains(ref.getName()) && refControl.canDelete());
    for (UiAction.Description d : UiActions.from(
        branchViews,
        new BranchResource(refControl.getProjectControl(), info),
        Providers.of(refControl.getCurrentUser()))) {
      if (info.actions == null) {
        info.actions = new TreeMap<>();
      }
      info.actions.put(d.getId(), new ActionInfo(d));
    }
    FluentIterable<WebLinkInfo> links =
        webLinks.getBranchLinks(
            refControl.getProjectControl().getProject().getName(), ref.getName());
    info.webLinks = links.isEmpty() ? null : links.toList();
    return info;
  }

  public static class BranchInfo {
    public String ref;
    public String revision;
    public Boolean canDelete;
    public Map<String, ActionInfo> actions;
    public List<WebLinkInfo> webLinks;

    public BranchInfo(String ref, String revision, boolean canDelete) {
      this.ref = ref;
      this.revision = revision;
      this.canDelete = canDelete;
    }

    void setCanDelete(boolean canDelete) {
      this.canDelete = canDelete ? true : null;
    }
  }
}
