/*
 * Copyright 2010-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.
 */

#include "slang_rs_reflect_utils.h"

#include <cstdio>
#include <cstring>
#include <string>
#include <iomanip>

#include "llvm/ADT/StringRef.h"

#include "os_sep.h"
#include "slang_assert.h"
#include "slang_utils.h"

namespace slang {

using std::string;

string RSSlangReflectUtils::GetFileNameStem(const char *fileName) {
  const char *dot = fileName + strlen(fileName);
  const char *slash = dot - 1;
  while (slash >= fileName) {
    if (*slash == OS_PATH_SEPARATOR) {
      break;
    }
    if ((*slash == '.') && (*dot == 0)) {
      dot = slash;
    }
    --slash;
  }
  ++slash;
  return string(slash, dot - slash);
}

string RSSlangReflectUtils::ComputePackagedPath(const char *prefixPath,
                                                const char *packageName) {
  string packaged_path(prefixPath);
  if (!packaged_path.empty() &&
      (packaged_path[packaged_path.length() - 1] != OS_PATH_SEPARATOR)) {
    packaged_path += OS_PATH_SEPARATOR_STR;
  }
  size_t s = packaged_path.length();
  packaged_path += packageName;
  while (s < packaged_path.length()) {
    if (packaged_path[s] == '.') {
      packaged_path[s] = OS_PATH_SEPARATOR;
    }
    ++s;
  }
  return packaged_path;
}

static string InternalFileNameConvert(const char *rsFileName, bool toLower) {
  const char *dot = rsFileName + strlen(rsFileName);
  const char *slash = dot - 1;
  while (slash >= rsFileName) {
    if (*slash == OS_PATH_SEPARATOR) {
      break;
    }
    if ((*slash == '.') && (*dot == 0)) {
      dot = slash;
    }
    --slash;
  }
  ++slash;
  char ret[256];
  int i = 0;
  for (; (i < 255) && (slash < dot); ++slash) {
    if (isalnum(*slash) || *slash == '_') {
      if (toLower) {
        ret[i] = tolower(*slash);
      } else {
        ret[i] = *slash;
      }
      ++i;
    }
  }
  ret[i] = 0;
  return string(ret);
}

std::string
RSSlangReflectUtils::JavaClassNameFromRSFileName(const char *rsFileName) {
  return InternalFileNameConvert(rsFileName, false);
}

std::string RootNameFromRSFileName(const std::string &rsFileName) {
  return InternalFileNameConvert(rsFileName.c_str(), false);
}

std::string
RSSlangReflectUtils::BCFileNameFromRSFileName(const char *rsFileName) {
  return InternalFileNameConvert(rsFileName, true);
}

std::string RSSlangReflectUtils::JavaBitcodeClassNameFromRSFileName(
    const char *rsFileName) {
  std::string tmp(InternalFileNameConvert(rsFileName, false));
  return tmp.append("BitCode");
}

static bool GenerateAccessorMethod(
    const RSSlangReflectUtils::BitCodeAccessorContext &context,
    int bitwidth, GeneratedFile &out) {
  // the prototype of the accessor method
  out.indent() << "// return byte array representation of the " << bitwidth
               << "-bit bitcode.\n";
  out.indent() << "public static byte[] getBitCode" << bitwidth << "()";
  out.startBlock();
  out.indent() << "return getBitCode" << bitwidth << "Internal();\n";
  out.endBlock(true);
  return true;
}

// Java method size must not exceed 64k,
// so we have to split the bitcode into multiple segments.
static bool GenerateSegmentMethod(const char *buff, int blen, int bitwidth,
                                  int seg_num, GeneratedFile &out) {
  out.indent() << "private static byte[] getSegment" << bitwidth << "_"
               << seg_num << "()";
  out.startBlock();
  out.indent() << "byte[] data = {";
  out.increaseIndent();

  const int kEntriesPerLine = 16;
  int position = kEntriesPerLine;  // We start with a new line and indent.
  for (int written = 0; written < blen; written++) {
    if (++position >= kEntriesPerLine) {
      out << "\n";
      out.indent();
      position = 0;
    } else {
      out << " ";
    }
    out << std::setw(4) << static_cast<int>(buff[written]) << ",";
  }
  out << "\n";

  out.decreaseIndent();
  out.indent() << "};\n";
  out.indent() << "return data;\n";
  out.endBlock();

  return true;
}

static bool GenerateJavaCodeAccessorMethodForBitwidth(
    const RSSlangReflectUtils::BitCodeAccessorContext &context,
    int bitwidth, GeneratedFile &out) {

  std::string filename(context.bc32FileName);
  if (bitwidth == 64) {
    filename = context.bc64FileName;
  }

  FILE *pfin = fopen(filename.c_str(), "rb");
  if (pfin == NULL) {
    fprintf(stderr, "Error: could not read file %s\n", filename.c_str());
    return false;
  }

  // start the accessor method
  GenerateAccessorMethod(context, bitwidth, out);

  // output the data
  // make sure the generated function for a segment won't break the Javac
  // size limitation (64K).
  static const int SEG_SIZE = 0x2000;
  char *buff = new char[SEG_SIZE];
  int read_length;
  int seg_num = 0;
  int total_length = 0;
  while ((read_length = fread(buff, 1, SEG_SIZE, pfin)) > 0) {
    GenerateSegmentMethod(buff, read_length, bitwidth, seg_num, out);
    ++seg_num;
    total_length += read_length;
  }
  delete[] buff;
  fclose(pfin);

  // output the internal accessor method
  out.indent() << "private static int bitCode" << bitwidth << "Length = "
               << total_length << ";\n\n";
  out.indent() << "private static byte[] getBitCode" << bitwidth
               << "Internal()";
  out.startBlock();
  out.indent() << "byte[] bc = new byte[bitCode" << bitwidth << "Length];\n";
  out.indent() << "int offset = 0;\n";
  out.indent() << "byte[] seg;\n";
  for (int i = 0; i < seg_num; ++i) {
    out.indent() << "seg = getSegment" << bitwidth << "_" << i << "();\n";
    out.indent() << "System.arraycopy(seg, 0, bc, offset, seg.length);\n";
    out.indent() << "offset += seg.length;\n";
  }
  out.indent() << "return bc;\n";
  out.endBlock();

  return true;
}

static bool GenerateJavaCodeAccessorMethod(
    const RSSlangReflectUtils::BitCodeAccessorContext &context,
    GeneratedFile &out) {
  if (!GenerateJavaCodeAccessorMethodForBitwidth(context, 32, out)) {
    slangAssert(false && "Couldn't generate 32-bit embedded bitcode!");
    return false;
  }
  if (!GenerateJavaCodeAccessorMethodForBitwidth(context, 64, out)) {
    slangAssert(false && "Couldn't generate 64-bit embedded bitcode!");
    return false;
  }

  return true;
}

static bool GenerateAccessorClass(
    const RSSlangReflectUtils::BitCodeAccessorContext &context,
    const char *clazz_name, GeneratedFile &out) {
  // begin the class.
  out << "/**\n";
  out << " * @hide\n";
  out << " */\n";
  out << "public class " << clazz_name;
  out.startBlock();

  bool ret = true;
  switch (context.bcStorage) {
  case BCST_APK_RESOURCE:
    slangAssert(false &&
                "Invalid generation of bitcode accessor with resource");
    break;
  case BCST_JAVA_CODE:
    ret = GenerateJavaCodeAccessorMethod(context, out);
    break;
  default:
    ret = false;
  }

  // end the class.
  out.endBlock();

  return ret;
}

bool RSSlangReflectUtils::GenerateJavaBitCodeAccessor(
    const BitCodeAccessorContext &context) {
  string output_path =
      ComputePackagedPath(context.reflectPath, context.packageName);
  if (!SlangUtils::CreateDirectoryWithParents(llvm::StringRef(output_path),
                                              NULL)) {
    fprintf(stderr, "Error: could not create dir %s\n", output_path.c_str());
    return false;
  }

  string clazz_name(JavaBitcodeClassNameFromRSFileName(context.rsFileName));
  string filename(clazz_name);
  filename += ".java";

  GeneratedFile out;
  if (!out.startFile(output_path, filename, context.rsFileName,
                     context.licenseNote, true, context.verbose)) {
    return false;
  }

  out << "package " << context.packageName << ";\n\n";

  bool ret = GenerateAccessorClass(context, clazz_name.c_str(), out);

  out.closeFile();
  return ret;
}

std::string JoinPath(const std::string &path1, const std::string &path2) {
  if (path1.empty()) {
    return path2;
  }
  if (path2.empty()) {
    return path1;
  }
  std::string fullPath = path1;
  if (fullPath[fullPath.length() - 1] != OS_PATH_SEPARATOR) {
    fullPath += OS_PATH_SEPARATOR;
  }
  if (path2[0] == OS_PATH_SEPARATOR) {
    fullPath += path2.substr(1, string::npos);
  } else {
    fullPath += path2;
  }
  return fullPath;
}

// Replace all instances of "\" with "\\" in a single string to prevent
// formatting errors.  In Java, this can happen even within comments, as
// Java processes \u before the comments are stripped.  E.g. if the generated
// file in Windows contains the note:
//     /* Do not modify!  Generated from \Users\MyName\MyDir\foo.cs */
// Java will think that \U tells of a Unicode character.
static void SanitizeString(std::string *s) {
  size_t p = 0;
  while ((p = s->find('\\', p)) != std::string::npos) {
    s->replace(p, 1, "\\\\");
    p += 2;
  }
}

static const char *const gApacheLicenseNote =
    "/*\n"
    " * Copyright (C) 2011-2014 The Android Open Source Project\n"
    " *\n"
    " * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
    " * you may not use this file except in compliance with the License.\n"
    " * You may obtain a copy of the License at\n"
    " *\n"
    " *      http://www.apache.org/licenses/LICENSE-2.0\n"
    " *\n"
    " * Unless required by applicable law or agreed to in writing, software\n"
    " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
    " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or "
    "implied.\n"
    " * See the License for the specific language governing permissions and\n"
    " * limitations under the License.\n"
    " */\n"
    "\n";

bool GeneratedFile::startFile(const string &outDirectory,
                              const string &outFileName,
                              const string &sourceFileName,
                              const string *optionalLicense, bool isJava,
                              bool verbose) {
  if (verbose) {
    printf("Generating %s\n", outFileName.c_str());
  }

  // Create the parent directories.
  if (!outDirectory.empty()) {
    std::string errorMsg;
    if (!SlangUtils::CreateDirectoryWithParents(outDirectory, &errorMsg)) {
      fprintf(stderr, "Error: %s\n", errorMsg.c_str());
      return false;
    }
  }

  std::string FilePath = JoinPath(outDirectory, outFileName);

  // Open the file.
  open(FilePath.c_str());
  if (!good()) {
    fprintf(stderr, "Error: could not write file %s\n", outFileName.c_str());
    return false;
  }

  // Write the license.
  if (optionalLicense != NULL) {
    *this << *optionalLicense;
  } else {
    *this << gApacheLicenseNote;
  }

  // Write a notice that this is a generated file.
  std::string source(sourceFileName);
  if (isJava) {
    SanitizeString(&source);
  }

  *this << "/*\n"
        << " * This file is auto-generated. DO NOT MODIFY!\n"
        << " * The source Renderscript file: " << source << "\n"
        << " */\n\n";

  return true;
}

void GeneratedFile::closeFile() { close(); }

void GeneratedFile::increaseIndent() { mIndent.append("    "); }

void GeneratedFile::decreaseIndent() {
  slangAssert(!mIndent.empty() && "No indent");
  mIndent.erase(0, 4);
}

void GeneratedFile::comment(const std::string &s) {
  indent() << "/* ";
  // +3 for the " * " starting each line.
  std::size_t indentLength = mIndent.length() + 3;
  std::size_t lengthOfCommentOnLine = 0;
  const std::size_t maxPerLine = 80;
  for (std::size_t start = 0, length = s.length(), nextStart = 0;
       start < length; start = nextStart) {
    std::size_t p = s.find_first_of(" \n", start);
    std::size_t toCopy = 1;
    bool forceBreak = false;
    if (p == std::string::npos) {
      toCopy = length - start;
      nextStart = length;
    } else {
      toCopy = p - start;
      nextStart = p + 1;
      forceBreak = s[p] == '\n';
    }
    if (lengthOfCommentOnLine > 0) {
      if (indentLength + lengthOfCommentOnLine + toCopy >= maxPerLine) {
        *this << "\n";
        indent() << " * ";
        lengthOfCommentOnLine = 0;
      } else {
        *this << " ";
      }
    }

    *this << s.substr(start, toCopy);
    if (forceBreak) {
      lengthOfCommentOnLine = maxPerLine;
    } else {
      lengthOfCommentOnLine += toCopy;
    }
  }
  *this << "\n";
  indent() << " */\n";
}

} // namespace slang
