// 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.annotations.PluginName;
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.reviewdb.server.ReviewDb;
import com.google.gerrit.server.mime.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;
  private final Provider<ReviewDb> db;
  private final String pluginName;

  @Inject
  public PostImage(FileTypeRegistry registry, Provider<IdentifiedUser> self,
      GitRepositoryManager repoManager, GitReferenceUpdated referenceUpdated,
      ChangeHooks hooks, @GerritPersonIdent PersonIdent myIdent,
      @CanonicalWebUrl String canonicalWebUrl, @GerritServerConfig Config cfg,
      Provider<ReviewDb> db, @PluginName String pluginName) {
    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;
    this.db = db;
    this.pluginName = pluginName;
  }

  @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 {
    long maxSize = getEffectiveMaxObjectSizeLimit(pc.getProjectState());
    // maxSize == 0 means that there is no limit
    if (maxSize > 0 && content.length > maxSize) {
      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(db.get(), 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("/");
    }
    url.append("plugins/");
    url.append(IdString.fromDecoded(pluginName).encoded());
    url.append("/project/");
    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;
    }
  }
}
