// Copyright 2012 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;

import static com.google.common.base.Preconditions.checkState;
import static org.eclipse.jgit.lib.Constants.OBJ_COMMIT;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.io.BaseEncoding;
import com.google.template.soy.data.SoyListData;
import com.google.template.soy.data.SoyMapData;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import org.eclipse.jgit.diff.RawText;
import org.eclipse.jgit.errors.LargeObjectException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.util.RawParseUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import prettify.parser.Prettify;
import syntaxhighlight.ParseResult;

/** Soy data converter for git blobs. */
public class BlobSoyData {
  private static final Logger log = LoggerFactory.getLogger(BlobSoyData.class);

  /**
   * Maximum number of bytes to load from a supposed text file for display. Files larger than this
   * will be displayed as binary files, even if the contents was text. For example really big XML
   * files may be above this limit and will get displayed as binary.
   */
  @VisibleForTesting static final int MAX_FILE_SIZE = 10 << 20;

  /**
   * Maximum number of lines to be displayed. Files larger than this will be displayed as binary
   * files, even on a text content. For example really big XML files may be above this limit and
   * will get displayed as binary.
   */
  private static final int MAX_LINE_COUNT = 50000;

  /** Allowed image extensions to render */
  private static final ImmutableSet<String> ALLOWED_IMAGE_TYPES =
      ImmutableSet.of(
          "image/gif", "image/jpeg", "image/jpg", "image/png", "image/tiff", "image/webp");

  private final GitilesView view;
  private final ObjectReader reader;

  public BlobSoyData(ObjectReader reader, GitilesView view) {
    this.reader = reader;
    this.view = view;
  }

  public Map<String, Object> toSoyData(ObjectId blobId) throws MissingObjectException, IOException {
    return toSoyData(null, blobId);
  }

  public Map<String, Object> toSoyData(String path, ObjectId blobId)
      throws MissingObjectException, IOException {
    Map<String, Object> data = Maps.newHashMapWithExpectedSize(4);
    data.put("sha", ObjectId.toString(blobId));

    ObjectLoader loader = reader.open(blobId, Constants.OBJ_BLOB);
    String content;
    String imageBlob;
    try {
      byte[] raw = loader.getCachedBytes(MAX_FILE_SIZE);

      String type = MimeTypes.getMimeType(path);
      if (ALLOWED_IMAGE_TYPES.contains(type) && raw.length < MAX_FILE_SIZE) {
        imageBlob = "data:" + type + ";base64," + BaseEncoding.base64().encode(raw);
      } else {
        imageBlob = null;
      }
      content =
          (raw.length < MAX_FILE_SIZE && !RawText.isBinary(raw)) ? RawParseUtils.decode(raw) : null;
      if (isContentTooLargeForDisplay(content)) {
        content = null;
      }
    } catch (LargeObjectException.OutOfMemory e) {
      throw e;
    } catch (LargeObjectException e) {
      content = null;
      imageBlob = null;
    }

    if (content != null) {
      data.put("lines", prettify(path, content));
      if (path != null && path.endsWith(".md")) {
        data.put("docUrl", GitilesView.doc().copyFrom(view).toUrl());
      }
    } else {
      data.put("lines", null);
      data.put("size", Long.toString(loader.getSize()));
    }
    if (path != null && view.getRevision().getPeeledType() == OBJ_COMMIT) {
      data.put("fileUrl", GitilesView.path().copyFrom(view).toUrl());
      data.put("logUrl", GitilesView.log().copyFrom(view).toUrl());
      data.put("blameUrl", GitilesView.blame().copyFrom(view).toUrl());
      if (imageBlob != null) {
        data.put("imgBlob", imageBlob);
      }
    }
    return data;
  }

  private SoyListData prettify(String path, String content) {
    List<ParseResult> results = parse(path, content);
    SoyListData lines = new SoyListData();
    SoyListData line = new SoyListData();
    lines.add(line);

    int last = 0;
    for (ParseResult r : results) {
      checkState(
          r.getOffset() >= last,
          "out-of-order ParseResult, expected %s >= %s",
          r.getOffset(),
          last);
      writeResult(lines, null, content, last, r.getOffset());
      last = r.getOffset() + r.getLength();
      writeResult(lines, r.getStyleKeysString(), content, r.getOffset(), last);
    }
    if (last < content.length()) {
      writeResult(lines, null, content, last, content.length());
    }
    return lines;
  }

  private List<ParseResult> parse(String path, String content) {
    String lang = extension(path, content);
    try {
      return ThreadSafePrettifyParser.INSTANCE.parse(lang, content);
    } catch (StackOverflowError e) {
      // TODO(dborowitz): Aaagh. Make prettify use RE2. Or replace it something
      // else. Or something.
      log.warn("StackOverflowError prettifying {}", view.toUrl());
      return ImmutableList.of(
          new ParseResult(0, content.length(), ImmutableList.of(Prettify.PR_PLAIN)));
    }
  }

  private static void writeResult(SoyListData lines, String classes, String s, int start, int end) {
    SoyListData line = lines.getListData(lines.length() - 1);
    while (true) {
      int nl = nextLineBreak(s, start, end);
      if (nl < 0) {
        break;
      }
      addSpan(line, classes, s, start, nl);

      start = nl + 1;
      if (start == s.length()) {
        return;
      }
      line = new SoyListData();
      lines.add(line);
    }
    addSpan(line, classes, s, start, end);
  }

  private static void addSpan(SoyListData line, String classes, String s, int start, int end) {
    if (end - start > 0) {
      if (Strings.isNullOrEmpty(classes)) {
        classes = Prettify.PR_PLAIN;
      }
      line.add(new SoyMapData("classes", classes, "text", s.substring(start, end)));
    }
  }

  private static int nextLineBreak(String s, int start, int end) {
    int n = s.indexOf('\n', start);
    return n < end ? n : -1;
  }

  private static @Nullable String extension(String path, String content) {
    if (content.startsWith("#!/bin/sh") || content.startsWith("#!/bin/bash")) {
      return "sh";
    } else if (content.startsWith("#!/usr/bin/perl")) {
      return "pl";
    } else if (content.startsWith("#!/usr/bin/python")) {
      return "py";
    } else if (path == null) {
      return null;
    }

    int slash = path.lastIndexOf('/');
    int dot = path.lastIndexOf('.');
    String ext = ((0 < dot) && (slash < dot)) ? path.substring(dot + 1) : null;
    if ("mk".equalsIgnoreCase(ext)) {
      return "sh";
    } else if ("Makefile".equalsIgnoreCase(path)
        || ((0 < slash) && "Makefile".equalsIgnoreCase(path.substring(slash + 1)))) {
      return "sh";
    } else {
      return ext;
    }
  }

  private static boolean isContentTooLargeForDisplay(String content) {
    if (content == null) {
      return false;
    }

    int lines = 0;
    int nl = -1;
    while (true) {
      nl = nextLineBreak(content, nl + 1, content.length());
      if (nl < 0) {
        return false;
      } else if (++lines == MAX_LINE_COUNT) {
        return true;
      }
    }
  }
}
