// 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.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;
  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,
      @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.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(rw, rw.parseCommit(commitId), false)) {
            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;
    }
  }
}
