/*
 * Copyright 2013, 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 <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <sstream>
#include <sys/stat.h>
#if ENABLE_PARALLEL_LLVM_CG
#include <cpu-features.h>
#endif
#include "Abcc_device.h"
using namespace abcc;

#if defined(__arm__) && defined(__ARM_ARCH_7A__)
# define CURRENT_ABI  "armeabi-v7a"
#elif defined(__arm__)
# define CURRENT_ABI  "armeabi"
#elif defined(__i386__)
# define CURRENT_ABI  "x86"
#elif defined(__mips__)
# define CURRENT_ABI  "mips"
#else
# error "Unsupport target abi"
#endif


DeviceBitcodeCompiler::DeviceBitcodeCompiler(const std::string &working_dir, const std::string &sysroot)
  : BitcodeCompiler(CURRENT_ABI, sysroot, working_dir) {}

void DeviceBitcodeCompiler::cleanupPost() {
  ReturnCode ret = mRet;
  std::string cmd("echo ");
  if (ret == RET_OK)
    cmd += "0";
  else
    cmd += "255";
  cmd += " > " + mWorkingDir + "/compile_result";
  runCmd(cmd);

  if (ret == RET_OK) {
    cmd = "rm -f " + mWorkingDir + "/compile_log";
    runCmd(cmd);
  }
  cmd = "chmod 0755 " + mWorkingDir + "/*";
  runCmd(cmd);
  mRet = ret; // Restore execution return code
}

int DeviceBitcodeCompiler::parseLDFlags(BitcodeInfo &info, const std::string &orig_str) {
  std::stringstream ss(orig_str);
  std::string str;
  while (ss >> str) {
    if (str.find("--sysroot") != std::string::npos) {
      continue;
    }
    if (str == "-o") {
      ss >> str;
      continue;
    }
    if (str == "-soname") {
      ss >> str;
      info.mSOName = str;
      continue;
    }
    if (str == "-shared") {
      info.mShared = true;
      info.mOutPath += ".so";
      continue;
    }

    // Parse -lxxx
    if (str.size() > 2 &&
        str.substr(0, 2) == "-l") {
      info.mLDLibs.push_back(str.substr(2));
      info.mLDLibsStr += " " + str;
      continue;
    }

    // Some other flags, like --no-undefined, -z now, -z noexecstack, ...
    info.mLDFlags += str + " ";
  } // while
  return 0;
}

void DeviceBitcodeCompiler::getBitcodeFiles() {
  std::vector<std::string> files;
  DIR *dp = opendir(mWorkingDir.c_str());
  if (!dp) {
    mRet = RET_FAIL_PREPARE_BITCODE;
    return;
  }

  struct dirent *entry = 0;
  while ((entry = readdir(dp)) != 0) {
    std::string filename(entry->d_name);
    std::string full_path = mWorkingDir + "/" + filename;
    if (filename == "." || filename == "..")
      continue;

    std::string libpath = mSysroot + "/usr/lib/" + filename.substr(0, filename.rfind('.')) + ".so";
    struct stat buf;
    if (stat(libpath.c_str(), &buf) == 0) {
      // This file has the same name in our runtime library pool.
      std::string cmd = "rm -f " + full_path;
      runCmd(cmd.c_str());
      continue;
    }


    int fd = open(full_path.c_str(), O_RDONLY);
    if (fd < 0) {
      LOGV("Error opening file: %s (Ignored)", full_path.c_str());
      continue;
    }

    unsigned char buffer[4];
    read(fd, buffer, 4);
    close(fd);
    BitcodeInfo::swapEndian(buffer, 4);
    int magic = BitcodeInfo::transferBytesToNum(buffer, 4);

    if (magic != 0x0b17c0de) {
      LOGV("Found file %s magic: %x, but we need a wrapped bitcode.", full_path.c_str(), magic);
      continue;
    }

    LOGV("Push_back a bitcode: %s", full_path.c_str());
    files.push_back(full_path);
  } // while
  closedir(dp);

  if (files.empty()) {
    LOGV("No bitcodes needs to compile");
    return;
  }

  if (returnCode() != RET_OK) {
    LOGV("Cannot get bitcode files from directory: %s", mWorkingDir.c_str());
    return;
  }

  for (std::vector<std::string>::const_iterator i = files.begin(),
       e = files.end(); i != e; ++i) {
    BitcodeInfo bcinfo(*i);
    if (bcinfo.readWrapper(*this) != 0) {
      LOGE("Cannot read wrapper for bitcode %s", i->c_str());
      mRet = RET_FAIL_PREPARE_BITCODE;
      return;
    }
    mBitcodeFiles.push_back(bcinfo);
  }
}

void DeviceBitcodeCompiler::prepareToolchain() {
  // le32-none-ndk-translate
  std::string cmd = std::string("LD_LIBRARY_PATH=") + mSysroot + "/usr/lib";
  cmd += " " + mSysroot + "/usr/bin/le32-none-ndk-translate";
  mExecutableToolsPath[(unsigned)CMD_TRANSLATE] = cmd;

  // llc
  cmd = std::string("LD_LIBRARY_PATH=") + mSysroot + "/usr/lib";
  cmd += " " + mSysroot + "/usr/bin/llc";
#ifdef ENABLE_PARALLEL_LLVM_CG
  std::ostringstream stream;
  stream << android_getCpuCount();
  cmd += " -thread=" + stream.str();
#endif
  mExecutableToolsPath[(unsigned)CMD_COMPILE] = cmd;

  // ld.mcld
  cmd = std::string("LD_LIBRARY_PATH=") + mSysroot + "/usr/lib";
  cmd += " " + mSysroot + "/usr/bin/ld.mcld";
  cmd += " -L" + mWorkingDir;
  cmd += " -L" + mSysroot + "/usr/lib";
  cmd += " -L/system/lib";
  mExecutableToolsPath[(unsigned)CMD_LINK] = cmd;

  cmd = " @" + mSysroot + "/usr/lib/libportable.wrap " + mSysroot + "/usr/lib/libportable.a";
  cmd += " " + mSysroot + "/usr/lib/libcompiler_rt_static.a";
  cmd += " " + mSysroot + "/usr/lib/libgabi++_shared.so";
  cmd += " -ldl";
  mExecutableToolsPath[(unsigned)CMD_LINK_RUNTIME] = cmd;
}

void DeviceBitcodeCompiler::copyRuntime(const BitcodeInfo &info) {
  runCmd(std::string("cp -f ") + mSysroot + "/usr/lib/libgabi++_shared.so " + mWorkingDir + "/libgabi++_shared.so");

  std::stringstream ss(info.mLDLibsStr);
  std::string deplib;
  while (ss >> deplib) {
    if (deplib.substr(0, 2) == "-l") {
      std::string libname = "lib" + deplib.substr(2) + ".so";
      std::string libpath = mSysroot + "/usr/lib/" + libname;
      struct stat buf;
      if (stat(libpath.c_str(), &buf) == 0) {
        // Found!
        LOGV("Copy runtime library: %s", libname.c_str());
        runCmd("cp -f " + libpath + " " + mWorkingDir + "/" + libname);
      }
    }
  }
}

void DeviceBitcodeCompiler::removeIntermediateFile(const std::string &path) {
  runCmd(std::string("rm -f ") + path);
}
