/*
 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.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 "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;
  
}






