// 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.googlesource.gerrit.plugins.imagare;

import com.google.gerrit.common.ChangeHooks;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.FileTypeRegistry;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.ProjectResource;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.project.RefControl;
import com.google.inject.Inject;
import com.google.inject.Provider;

import com.googlesource.gerrit.plugins.imagare.PostImage.Input;

import eu.medsea.mimeutil.MimeType;

import org.apache.commons.lang.ArrayUtils;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.TreeFormatter;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.util.Base64;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PostImage implements RestModifyView<ProjectResource, Input> {

  public static class Input {
    public String imageData;
    public String fileName;
  }

  private final FileTypeRegistry registry;
  private final Pattern imageDataPattern;
  private final Provider<IdentifiedUser> self;
  private final GitRepositoryManager repoManager;
  private final GitReferenceUpdated referenceUpdated;
  private final ChangeHooks hooks;
  private final PersonIdent myIdent;
  private final String canonicalWebUrl;
  private final Config cfg;

  @Inject
  public PostImage(FileTypeRegistry registry, Provider<IdentifiedUser> self,
      GitRepositoryManager repoManager, GitReferenceUpdated referenceUpdated,
      ChangeHooks hooks, @GerritPersonIdent PersonIdent myIdent,
      @CanonicalWebUrl String canonicalWebUrl, @GerritServerConfig Config cfg) {
    this.registry = registry;
    this.imageDataPattern = Pattern.compile("data:([\\w/.-]+);([\\w]+),(.*)");
    this.self = self;
    this.repoManager = repoManager;
    this.referenceUpdated = referenceUpdated;
    this.hooks = hooks;
    this.myIdent = myIdent;
    this.canonicalWebUrl = canonicalWebUrl;
    this.cfg = cfg;
  }

  @Override
  public Response<ImageInfo> apply(ProjectResource rsrc, Input input)
      throws MethodNotAllowedException, BadRequestException, AuthException,
      IOException, ResourceConflictException {
    if (input == null) {
      input = new Input();
    }
    ImageInfo info;
    if (input.imageData != null) {
      info = storeImage(rsrc.getControl(), input.imageData, input.fileName);
    } else {
      throw new BadRequestException("no image data");
    }
    return Response.created(info);
  }

  private ImageInfo storeImage(ProjectControl pc, String imageData,
      String fileName) throws MethodNotAllowedException, BadRequestException,
      AuthException, IOException, ResourceConflictException {
    Matcher m = imageDataPattern.matcher(imageData);
    if (m.matches()) {
      String receivedMimeType = m.group(1);
      String encoding = m.group(2);
      String encodedContent = m.group(3);

      if (fileName == null) {
        int pos = receivedMimeType.indexOf('/');
        if (pos > 0 && pos + 1 < receivedMimeType.length()) {
          fileName = "img." + receivedMimeType.substring(pos + 1);
        } else {
          throw new BadRequestException("bad mime type: " + receivedMimeType);
        }
      }

      if ("base64".equals(encoding)) {
        byte[] content = Base64.decode(encodedContent);
        MimeType mimeType =
            registry.getMimeType("img." + receivedMimeType, content);
        if (!"image".equals(mimeType.getMediaType())) {
          throw new MethodNotAllowedException("no image");
        }
        if (!receivedMimeType.equals(mimeType.toString())) {
          throw new BadRequestException("incorrect mime type");
        }
        return new ImageInfo(storeImage(pc, mimeType, content, fileName));
      } else {
        throw new MethodNotAllowedException("unsupported encoding");
      }
    } else {
      throw new BadRequestException("invalid image data");
    }
  }

  private String storeImage(ProjectControl pc, MimeType mimeType,
      byte[] content, String fileName) throws AuthException, IOException,
      ResourceConflictException {
    if (content.length > getEffectiveMaxObjectSizeLimit(pc.getProjectState())) {
      throw new ResourceConflictException("image too large");
    }

    String ref = getRef(content, fileName);
    RefControl rc = pc.controlForRef(ref);

    Repository repo = repoManager.openRepository(pc.getProject().getNameKey());
    try {
      ObjectId commitId = repo.resolve(ref);
      if (commitId != null) {
        // this image exists already
        return getUrl(pc.getProject().getNameKey(), ref, fileName);
      }

      RevWalk rw = new RevWalk(repo);
      try {
        ObjectInserter oi = repo.newObjectInserter();
        try {
          ObjectId blobId = oi.insert(Constants.OBJ_BLOB, content);
          oi.flush();

          TreeFormatter tf = new TreeFormatter();
          tf.append(fileName, FileMode.REGULAR_FILE, blobId);
          ObjectId treeId = tf.insertTo(oi);
          oi.flush();

          PersonIdent authorIdent =
              self.get().newCommitterIdent(myIdent.getWhen(), myIdent.getTimeZone());
          CommitBuilder cb = new CommitBuilder();
          cb.setTreeId(treeId);
          cb.setAuthor(authorIdent);
          cb.setCommitter(authorIdent);
          cb.setMessage("Image Upload");

          commitId = oi.insert(cb);
          oi.flush();

          if (!rc.canCreate(rw, rw.parseCommit(commitId))) {
            throw new AuthException(String.format(
                "Project %s doesn't allow image upload.", pc.getProject().getName()));
          }

          RefUpdate ru = repo.updateRef(ref);
          ru.setExpectedOldObjectId(ObjectId.zeroId());
          ru.setNewObjectId(commitId);
          ru.disableRefLog();
          if (ru.update(rw) == RefUpdate.Result.NEW) {
            referenceUpdated.fire(pc.getProject().getNameKey(), ru);
            hooks.doRefUpdatedHook(new Branch.NameKey(pc.getProject()
                .getNameKey(), ref), ru, self.get().getAccount());
          } else {
            throw new IOException(String.format(
                "Failed to create ref %s in %s: %s", ref,
                pc.getProject().getName(), ru.getResult()));
          }

          return getUrl(pc.getProject().getNameKey(), ref, fileName);
        } finally {
          oi.release();
        }

      } finally {
        rw.release();
      }
    } finally {
      repo.close();
    }

  }

  private String getRef(byte[] content, String fileName) {
    String id = new ObjectInserter.Formatter().idFor(Constants.OBJ_BLOB,
        ArrayUtils.addAll(content, fileName.getBytes())).getName();
    StringBuilder ref = new StringBuilder();
    ref.append(Constants.R_REFS);
    ref.append("images/");
    ref.append(id.substring(0, 2));
    ref.append("/");
    ref.append(id.substring(2));
    return ref.toString();
  }

  private String getUrl(Project.NameKey project, String rev, String fileName) {
    StringBuilder url = new StringBuilder();
    url.append(canonicalWebUrl);
    if (!canonicalWebUrl.endsWith("/")) {
      url.append("src/");
    }
    url.append("src/");
    url.append(IdString.fromDecoded(project.get()).encoded());
    url.append("/rev/");
    url.append(IdString.fromDecoded(rev).encoded());
    url.append("/");
    url.append(IdString.fromDecoded(fileName).encoded());
    return url.toString();
  }

  private long getEffectiveMaxObjectSizeLimit(ProjectState p) {
    long global = cfg.getLong("receive", "maxObjectSizeLimit", 0);
    long local = p.getMaxObjectSizeLimit();
    if (global > 0 && local > 0) {
      return Math.min(global, local);
    } else {
      // zero means "no limit", in this case the max is more limiting
      return Math.max(global, local);
    }
  }

  public static class ImageInfo {
    public String url;

    public ImageInfo(String url) {
      this.url = url;
    }
  }
}
