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