/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/
 *
 * Author: pgess <v.melnychenko@xreate.org>
 * Created on June 7, 2018, 3:35 PM
 *
 * \file    transcend.cpp
 * \brief   Transcend's tests
 */

#include "xreatemanager.h"
#include "transcendlayer.h"
#include "supplemental/docutils.h"
#include <gtest/gtest.h>

using namespace xreate;
using namespace std;

TEST(Transcend, Parse1) {
  std::string script =
    R"Code(
)Code";

  std::unique_ptr<details::tier1::XreateManager> man(details::tier1::XreateManager::prepare(std::move(script)));

  std::string scriptTranscend =
    R"Code(
    test1((1)).
    test2((1, 2)).
    test3(1, "a").
)Code";

  man->transcend->addRawScript(move(scriptTranscend));
  man->analyse();

  StaticModel solution = man->transcend->query("test1");
  Gringo::Symbol symbTest1 = solution.begin()->second;
  auto answer1 = man->transcend->parse<list<int>>(symbTest1);
  ASSERT_EQ(1, get<0>(answer1).size());

  solution = man->transcend->query("test2");
  Gringo::Symbol symbTest2 = solution.begin()->second;
  auto answer2 = get<0>(man->transcend->parse<list<int>>(symbTest2));
  ASSERT_EQ(2, answer2.size());

  typedef std::tuple<int, string> Predicate3;
  solution = man->transcend->query("test3");
  Gringo::Symbol symbTest3 = solution.begin()->second;
  auto answer3a = get<0>(man->transcend->parse(schemeT<Predicate3>(), symbTest3));
  auto answer3b = get<1>(man->transcend->parse(schemeT<Predicate3>(), symbTest3));
  ASSERT_EQ(1, answer3a);
  ASSERT_STREQ("a", answer3b.c_str());
}

TEST(Transcend, Doc_Expressions1) {
  string code = getDocumentationExampleById("documentation/Transcend/transcend.xml", "Expressions1");
  XreateManager* man = XreateManager::prepare(move(code));
  man->run();
  delete man;
  ASSERT_TRUE(true);
}

TEST(Transcend, Doc_SlaveTypes1){
  string code = getDocumentationExampleById("documentation/Transcend/transcend.xml", "Codeblocks1");
  XreateManager::prepare(move(code));

  ASSERT_TRUE(true);  
}

TEST(Transcend, Doc_Codeblocks1) {
  string code = getDocumentationExampleById("documentation/Transcend/transcend.xml", "Codeblocks1");
  XreateManager::prepare(move(code));

  ASSERT_TRUE(true);
}

TEST(Transcend, Doc_Diagnostics1) {
  string code = getDocumentationExampleById("documentation/Transcend/transcend.xml", "Diagnostics1");
  string scriptTranscend =  getDocumentationExampleById("documentation/Transcend/transcend.xml", "Diagnostics1_Rules");
  string scriptSupport = 
R"Code(
scope_func_dict(S, Fn):-
    cfa_parent(S, function(Fn)).
    
scope_func_dict(S1, Fn):-
    cfa_parent(S1, scope(S2));
    scope_func_dict(S2, Fn).
)Code";

  auto man = XreateManager::prepare(move(code));
  man->transcend->addRawScript(move(scriptTranscend));
  man->transcend->addRawScript(move(scriptSupport));
  testing::internal::CaptureStdout();
  
  man->run();
  delete man;
  
  std::string outputActual = testing::internal::GetCapturedStdout();
  std::cout << outputActual << std::endl;
  string outputExpected = "warning(\"Visibility violation\",\"test\",\"sum\")";
  ASSERT_NE(std::string::npos, outputActual.find(outputExpected));
}