// 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.change;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.gerrit.extensions.common.FileInfo;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.CacheControl;
import com.google.gerrit.extensions.restapi.ChildCollection;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.extensions.restapi.RestView;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountPatchReview;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.patch.PatchList;
import com.google.gerrit.server.patch.PatchListCache;
import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;

import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
import org.kohsuke.args4j.Option;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.concurrent.TimeUnit;

class Files implements ChildCollection<RevisionResource, FileResource> {
  private final DynamicMap<RestView<FileResource>> views;
  private final Provider<ListFiles> list;

  @Inject
  Files(DynamicMap<RestView<FileResource>> views, Provider<ListFiles> list) {
    this.views = views;
    this.list = list;
  }

  @Override
  public DynamicMap<RestView<FileResource>> views() {
    return views;
  }

  @Override
  public RestView<RevisionResource> list() throws AuthException {
    return list.get();
  }

  @Override
  public FileResource parse(RevisionResource rev, IdString id)
      throws ResourceNotFoundException, OrmException, AuthException {
    return new FileResource(rev, id.get());
  }

  private static final class ListFiles implements RestReadView<RevisionResource> {
    private static final Logger log = LoggerFactory.getLogger(ListFiles.class);

    @Option(name = "--base", metaVar = "revision-id")
    String base;

    @Option(name = "--reviewed")
    boolean reviewed;

    private final Provider<ReviewDb> db;
    private final Provider<CurrentUser> self;
    private final FileInfoJson fileInfoJson;
    private final Provider<Revisions> revisions;
    private final GitRepositoryManager gitManager;
    private final PatchListCache patchListCache;

    @Inject
    ListFiles(Provider<ReviewDb> db,
        Provider<CurrentUser> self,
        FileInfoJson fileInfoJson,
        Provider<Revisions> revisions,
        GitRepositoryManager gitManager,
        PatchListCache patchListCache) {
      this.db = db;
      this.self = self;
      this.fileInfoJson = fileInfoJson;
      this.revisions = revisions;
      this.gitManager = gitManager;
      this.patchListCache = patchListCache;
    }

    @Override
    public Response<?> apply(RevisionResource resource) throws AuthException,
        BadRequestException, ResourceNotFoundException, OrmException {
      if (base != null && reviewed) {
        throw new BadRequestException("cannot combine base and reviewed");
      } else if (reviewed) {
        return Response.ok(reviewed(resource));
      }

      PatchSet basePatchSet = null;
      if (base != null) {
        RevisionResource baseResource = revisions.get().parse(
            resource.getChangeResource(), IdString.fromDecoded(base));
        basePatchSet = baseResource.getPatchSet();
      }
      try {
        Response<Map<String, FileInfo>> r = Response.ok(fileInfoJson.toFileInfoMap(
            resource.getChange(),
            resource.getPatchSet(),
            basePatchSet));
        if (resource.isCacheable()) {
          r.caching(CacheControl.PRIVATE(7, TimeUnit.DAYS));
        }
        return r;
      } catch (PatchListNotAvailableException e) {
        throw new ResourceNotFoundException(e.getMessage());
      }
    }

    private List<String> reviewed(RevisionResource resource)
        throws AuthException, OrmException {
      CurrentUser user = self.get();
      if (!(user.isIdentifiedUser())) {
        throw new AuthException("Authentication required");
      }

      Account.Id userId = ((IdentifiedUser) user).getAccountId();
      List<String> r = scan(userId, resource.getPatchSet().getId());

      if (r.isEmpty() && 1 < resource.getPatchSet().getPatchSetId()) {
        for (Integer id : reverseSortPatchSets(resource)) {
          PatchSet.Id old = new PatchSet.Id(resource.getChange().getId(), id);
          List<String> o = scan(userId, old);
          if (!o.isEmpty()) {
            try {
              r = copy(Sets.newHashSet(o), old, resource, userId);
            } catch (IOException | PatchListNotAvailableException e) {
              log.warn("Cannot copy patch review flags", e);
            }
            break;
          }
        }
      }

      return r;
    }

    private List<String> scan(Account.Id userId, PatchSet.Id psId)
        throws OrmException {
      List<String> r = Lists.newArrayList();
      for (AccountPatchReview w : db.get().accountPatchReviews()
          .byReviewer(userId, psId)) {
        r.add(w.getKey().getPatchKey().getFileName());
      }
      return r;
    }

    private List<Integer> reverseSortPatchSets(
        RevisionResource resource) throws OrmException {
      SortedSet<Integer> ids = Sets.newTreeSet();
      for (PatchSet p : db.get().patchSets()
          .byChange(resource.getChange().getId())) {
        if (p.getPatchSetId() < resource.getPatchSet().getPatchSetId()) {
          ids.add(p.getPatchSetId());
        }
      }

      List<Integer> r = Lists.newArrayList(ids);
      Collections.reverse(r);
      return r;
    }

    private List<String> copy(Set<String> paths, PatchSet.Id old,
        RevisionResource resource, Account.Id userId) throws IOException,
        PatchListNotAvailableException, OrmException {
      Repository git =
          gitManager.openRepository(resource.getChange().getProject());
      try {
        ObjectReader reader = git.newObjectReader();
        try {
          PatchList oldList = patchListCache.get(
              resource.getChange(),
              db.get().patchSets().get(old));

          PatchList curList = patchListCache.get(
              resource.getChange(),
              resource.getPatchSet());

          int sz = paths.size();
          List<AccountPatchReview> inserts = Lists.newArrayListWithCapacity(sz);
          List<String> pathList = Lists.newArrayListWithCapacity(sz);

          RevWalk rw = new RevWalk(reader);
          TreeWalk tw = new TreeWalk(reader);
          tw.setFilter(PathFilterGroup.createFromStrings(paths));
          tw.setRecursive(true);
          int o = tw.addTree(rw.parseCommit(oldList.getNewId()).getTree());
          int c = tw.addTree(rw.parseCommit(curList.getNewId()).getTree());

          int op = -1;
          if (oldList.getOldId() != null) {
            op = tw.addTree(rw.parseTree(oldList.getOldId()));
          }

          int cp = -1;
          if (curList.getOldId() != null) {
            cp = tw.addTree(rw.parseTree(curList.getOldId()));
          }

          while (tw.next()) {
            String path = tw.getPathString();
            if (tw.getRawMode(o) != 0 && tw.getRawMode(c) != 0
                && tw.idEqual(o, c)
                && paths.contains(path)) {
              // File exists in previously reviewed oldList and in curList.
              // File content is identical.
              inserts.add(new AccountPatchReview(
                  new Patch.Key(
                      resource.getPatchSet().getId(),
                      path),
                    userId));
              pathList.add(path);
            } else if (op >= 0 && cp >= 0
                && tw.getRawMode(o) == 0 && tw.getRawMode(c) == 0
                && tw.getRawMode(op) != 0 && tw.getRawMode(cp) != 0
                && tw.idEqual(op, cp)
                && paths.contains(path)) {
              // File was deleted in previously reviewed oldList and curList.
              // File exists in ancestor of oldList and curList.
              // File content is identical in ancestors.
              inserts.add(new AccountPatchReview(
                  new Patch.Key(
                      resource.getPatchSet().getId(),
                      path),
                    userId));
              pathList.add(path);
            }
          }
          db.get().accountPatchReviews().insert(inserts);
          return pathList;
        } finally {
          reader.close();
        }
      } finally {
        git.close();
      }
    }
  }
}
