// Copyright (C) 2014 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;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Strings;
import com.google.common.collect.FluentIterable;
import com.google.gerrit.extensions.common.DiffWebLinkInfo;
import com.google.gerrit.extensions.common.WebLinkInfo;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.extensions.webui.BranchWebLink;
import com.google.gerrit.extensions.webui.DiffWebLink;
import com.google.gerrit.extensions.webui.FileWebLink;
import com.google.gerrit.extensions.webui.PatchSetWebLink;
import com.google.gerrit.extensions.webui.ProjectWebLink;
import com.google.gerrit.extensions.webui.WebLink;
import com.google.gerrit.reviewdb.client.Project;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Singleton
public class WebLinks {
  private static final Logger log = LoggerFactory.getLogger(WebLinks.class);
  private static final Predicate<WebLinkInfo> INVALID_WEBLINK =
      new Predicate<WebLinkInfo>() {

        @Override
        public boolean apply(WebLinkInfo link) {
          if (link == null){
            return false;
          } else if (Strings.isNullOrEmpty(link.name)
              || Strings.isNullOrEmpty(link.url)) {
            log.warn(String.format("%s is missing name and/or url",
                link.getClass().getName()));
            return false;
          }
          return true;
        }
      };

  private final DynamicSet<PatchSetWebLink> patchSetLinks;
  private final DynamicSet<FileWebLink> fileLinks;
  private final DynamicSet<DiffWebLink> diffLinks;
  private final DynamicSet<ProjectWebLink> projectLinks;
  private final DynamicSet<BranchWebLink> branchLinks;

  @Inject
  public WebLinks(DynamicSet<PatchSetWebLink> patchSetLinks,
      DynamicSet<FileWebLink> fileLinks,
      DynamicSet<DiffWebLink> diffLinks,
      DynamicSet<ProjectWebLink> projectLinks,
      DynamicSet<BranchWebLink> branchLinks) {
    this.patchSetLinks = patchSetLinks;
    this.fileLinks = fileLinks;
    this.diffLinks = diffLinks;
    this.projectLinks = projectLinks;
    this.branchLinks = branchLinks;
  }

  /**
   *
   * @param project Project name.
   * @param commit SHA1 of commit.
   * @return Links for patch sets.
   */
  public FluentIterable<WebLinkInfo> getPatchSetLinks(final Project.NameKey project,
      final String commit) {
    return filterLinks(patchSetLinks, new Function<WebLink, WebLinkInfo>() {

      @Override
      public WebLinkInfo apply(WebLink webLink) {
        return ((PatchSetWebLink)webLink).getPathSetWebLink(project.get(), commit);
      }
    });
  }

  /**
   *
   * @param project Project name.
   * @param revision SHA1 of revision.
   * @param file File name.
   * @return Links for files.
   */
  public FluentIterable<WebLinkInfo> getFileLinks(final String project, final String revision,
      final String file) {
    return filterLinks(fileLinks, new Function<WebLink, WebLinkInfo>() {

      @Override
      public WebLinkInfo apply(WebLink webLink) {
        return ((FileWebLink)webLink).getFileWebLink(project, revision, file);
      }
    });
  }

  /**
   *
   * @param project Project name.
   * @param patchSetIdA Patch set ID of side A, <code>null</code> if no base
   *        patch set was selected.
   * @param revisionA SHA1 of revision of side A.
   * @param fileA File name of side A.
   * @param patchSetIdB Patch set ID of side B.
   * @param revisionB SHA1 of revision of side B.
   * @param fileB File name of side B.
   * @return Links for file diffs.
   */
  public FluentIterable<DiffWebLinkInfo> getDiffLinks(final String project, final int changeId,
      final Integer patchSetIdA, final String revisionA, final String fileA,
      final int patchSetIdB, final String revisionB, final String fileB) {
   return FluentIterable
       .from(diffLinks)
       .transform(new Function<WebLink, DiffWebLinkInfo>() {
         @Override
         public DiffWebLinkInfo apply(WebLink webLink) {
            return ((DiffWebLink) webLink).getDiffLink(project, changeId,
                patchSetIdA, revisionA, fileA,
                patchSetIdB, revisionB, fileB);
          }
       })
       .filter(INVALID_WEBLINK);
 }

  /**
   *
   * @param project Project name.
   * @return Links for projects.
   */
  public FluentIterable<WebLinkInfo> getProjectLinks(final String project) {
    return filterLinks(projectLinks, new Function<WebLink, WebLinkInfo>() {

      @Override
      public WebLinkInfo apply(WebLink webLink) {
        return ((ProjectWebLink)webLink).getProjectWeblink(project);
      }
    });
  }

  /**
   *
   * @param project Project name
   * @param branch Branch name
   * @return Links for branches.
   */
  public FluentIterable<WebLinkInfo> getBranchLinks(final String project, final String branch) {
    return filterLinks(branchLinks, new Function<WebLink, WebLinkInfo>() {

      @Override
      public WebLinkInfo apply(WebLink webLink) {
        return ((BranchWebLink)webLink).getBranchWebLink(project, branch);
      }
    });
  }

  private FluentIterable<WebLinkInfo> filterLinks(DynamicSet<? extends WebLink> links,
      Function<WebLink, WebLinkInfo> transformer) {
    return FluentIterable
        .from(links)
        .transform(transformer)
        .filter(INVALID_WEBLINK);
  }
}