// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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.gitiles.doc;

import com.google.common.collect.ImmutableSet;
import com.google.common.io.BaseEncoding;
import com.google.gitiles.GitilesView;
import com.google.gitiles.MimeTypes;
import java.io.IOException;
import javax.annotation.Nullable;
import org.eclipse.jgit.errors.LargeObjectException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Reads an image from Git and converts to {@code data:image/*;base64,...} */
class ImageLoader {
  private static final Logger log = LoggerFactory.getLogger(ImageLoader.class);
  private static final ImmutableSet<String> ALLOWED_TYPES =
      ImmutableSet.of("image/gif", "image/jpeg", "image/png", "image/webp");

  private final ObjectReader reader;
  private final GitilesView view;
  private final MarkdownConfig config;
  private final RevTree root;

  ImageLoader(ObjectReader reader, GitilesView view, MarkdownConfig config, RevTree root) {
    this.reader = reader;
    this.view = view;
    this.config = config;
    this.root = root;
  }

  String inline(@Nullable String markdownPath, String imagePath) {
    String data = inlineMaybe(markdownPath, imagePath);
    if (data != null) {
      return data;
    }
    // Otherwise return something that is both clearly an image, but clearly invalid.
    return SoyConstants.IMAGE_URI_INNOCUOUS_OUTPUT;
  }

  private String inlineMaybe(@Nullable String markdownPath, String imagePath) {
    if (config.imageLimit <= 0) {
      return null;
    }

    String path = PathResolver.resolve(markdownPath, imagePath);
    if (path == null) {
      return null;
    }

    String type = MimeTypes.getMimeType(path);
    if (!ALLOWED_TYPES.contains(type)) {
      return null;
    }

    try {
      TreeWalk tw = TreeWalk.forPath(reader, path, root);
      if (tw == null || tw.getFileMode(0) != FileMode.REGULAR_FILE) {
        return null;
      }

      ObjectId id = tw.getObjectId(0);
      byte[] raw = reader.open(id, Constants.OBJ_BLOB).getCachedBytes(config.imageLimit);
      if (raw.length > config.imageLimit) {
        return null;
      }
      return "data:" + type + ";base64," + BaseEncoding.base64().encode(raw);
    } catch (LargeObjectException.ExceedsLimit e) {
      return null;
    } catch (IOException err) {
      String repo = view != null ? view.getRepositoryName() : "<unknown>";
      log.error(
          String.format("cannot read repo %s image %s from %s", repo, path, root.name()), err);
      return null;
    }
  }
}
