/*
 Copyright 2019 Alain Dargelas

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

/*
 * File:   PythonAPICache.cpp
 * Author: alain
 *
 * Created on May 28, 2017, 10:49 PM
 */

#include "CommandLine/CommandLineParser.hpp"
#include "ErrorReporting/ErrorContainer.h"
#include "SourceCompile/SymbolTable.h"
#include "SourceCompile/CompilationUnit.h"
#include "SourceCompile/PreprocessFile.h"
#include "SourceCompile/CompileSourceFile.h"
#include "SourceCompile/Compiler.h"
#include "SourceCompile/ParseFile.h"
#include "Utils/StringUtils.h"
#include "Utils/FileUtils.h"
#include "Cache/Cache.h"
#include "flatbuffers/util.h"
#include <cstdio>
#include <ctime>
#include <sys/types.h>
#include <sys/stat.h>

#include "antlr4-runtime.h"
using namespace antlr4;

#include "API/PythonAPI.h"
#include "Cache/PythonAPICache.h"
#include "SourceCompile/PythonListen.h"

using namespace SURELOG;

static std::string FlbSchemaVersion = "1.0";

PythonAPICache::PythonAPICache(PythonListen* listener) : m_listener(listener) {}

PythonAPICache::PythonAPICache(const PythonAPICache& orig) {}

PythonAPICache::~PythonAPICache() {}

std::string PythonAPICache::getCacheFileName_(std::string svFileName) {
  SymbolId cacheDirId =
      m_listener->getCompileSourceFile()->getCommandLineParser()->getCacheDir();
  std::string cacheDirName = m_listener->getParseFile()->getSymbol(cacheDirId);
  if (svFileName == "")
    svFileName = m_listener->getParseFile()->getFileName(LINE1);
  svFileName = StringUtils::getRootFileName(svFileName);
  Library* lib = m_listener->getCompileSourceFile()->getLibrary();
  std::string libName = lib->getName() + "/";
  std::string cacheFileName = cacheDirName + libName + svFileName + ".slpy";
  return cacheFileName;
}

bool PythonAPICache::restore_(std::string cacheFileName) {
  uint8_t* buffer_pointer = openFlatBuffers(cacheFileName);
  if (buffer_pointer == NULL) return false;

  const PYTHONAPICACHE::PythonAPICache* ppcache =
      PYTHONAPICACHE::GetPythonAPICache(buffer_pointer);
  SymbolTable canonicalSymbols;
  restoreErrors(ppcache->m_errors(), ppcache->m_symbols(), canonicalSymbols,
                m_listener->getCompileSourceFile()->getErrorContainer(),
                m_listener->getCompileSourceFile()->getSymbolTable());

  delete[] buffer_pointer;
  return true;
}

bool PythonAPICache::checkCacheIsValid_(std::string cacheFileName) {
  uint8_t* buffer_pointer = openFlatBuffers(cacheFileName);
  if (buffer_pointer == NULL) return false;
  if (!PYTHONAPICACHE::PythonAPICacheBufferHasIdentifier(buffer_pointer)) {
    delete[] buffer_pointer;
    return false;
  }
  const PYTHONAPICACHE::PythonAPICache* ppcache =
      PYTHONAPICACHE::GetPythonAPICache(buffer_pointer);
  auto header = ppcache->m_header();

  auto scriptFile = ppcache->m_python_script_file()->c_str();
  if (scriptFile) {
    time_t ct = get_mtime(cacheFileName.c_str());
    time_t ft = get_mtime(scriptFile);
    if (ft == -1) {
      delete[] buffer_pointer;
      return false;
    }
    if (ct == -1) {
      delete[] buffer_pointer;
      return false;
    }
    if (ct < ft) {
      delete[] buffer_pointer;
      return false;
    }
  }

  if (!checkIfCacheIsValid(header, FlbSchemaVersion, cacheFileName)) {
    delete[] buffer_pointer;
    return false;
  }

  delete[] buffer_pointer;
  return true;
}

bool PythonAPICache::isValid() {
  std::string cacheFileName = getCacheFileName_();
  return checkCacheIsValid_(cacheFileName);
}

bool PythonAPICache::restore() {
  bool cacheAllowed = m_listener->getCompileSourceFile()
                          ->getCommandLineParser()
                          ->cacheAllowed();
  if (!cacheAllowed) return false;

  std::string cacheFileName = getCacheFileName_();
  if (!checkCacheIsValid_(cacheFileName)) {
    return false;
  }

  return restore_(cacheFileName);
}

bool PythonAPICache::save() {
  bool cacheAllowed = m_listener->getCompileSourceFile()
                          ->getCommandLineParser()
                          ->cacheAllowed();
  if (!cacheAllowed) return false;
  std::string svFileName = m_listener->getParseFile()->getPpFileName();
  std::string origFileName = svFileName;

  std::string cacheFileName = getCacheFileName_();

  flatbuffers::FlatBufferBuilder builder(1024);
  /* Create header section */
  auto header = createHeader(builder, FlbSchemaVersion, origFileName);

  std::string pythonScriptFile = PythonAPI::getListenerScript();
  auto scriptFile = builder.CreateString(pythonScriptFile);

  /* Cache the errors and canonical symbols */
  ErrorContainer* errorContainer =
      m_listener->getCompileSourceFile()->getErrorContainer();
  SymbolId subjectFileId = m_listener->getParseFile()->getFileId(LINE1);
  SymbolTable canonicalSymbols;
  auto errorSymbolPair = cacheErrors(
      builder, canonicalSymbols, errorContainer,
      m_listener->getCompileSourceFile()->getSymbolTable(), subjectFileId);

  /* Create Flatbuffers */
  auto ppcache = PYTHONAPICACHE::CreatePythonAPICache(
      builder, header, scriptFile, errorSymbolPair.first,
      errorSymbolPair.second);
  FinishPythonAPICacheBuffer(builder, ppcache);

  /* Save Flatbuffer */
  bool status = saveFlatbuffers(builder, cacheFileName);

  return status;
}
