/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Author: pgess <v.melnychenko@xreate.org>
 * Created on: Jan, 2020
*/
#ifndef XREATE_TRANSCENDTARGET_H
#define XREATE_TRANSCENDTARGET_H

#include "pass/abstractpass.h"
#include "transcendlayer.h"

namespace xreate{
//struct TranscendTag{};
//class TranscendScope;
//class TranscendFn;
//class TranscendTarget;
//
//typedef std::list<std::string> TranscendResult;
//
//template<>
//struct compilation::TargetInfo<TranscendTag>{
//public:
//  typedef TranscendResult Result;
//  typedef TranscendFn Function;
//  typedef TranscendScope Scope;
//};
//
//class TranscendScope: public compilation::Scope<TranscendTag>{
//  typedef compilation::Scope<TranscendTag> Parent;
//
//public:
//  TranscendScope(const CodeScope* codeScope, compilation::Function<TranscendTag>* f): Parent(codeScope, f){}
//  TranscendResult processMetaSymbol(const Symbol& s);
//  TranscendResult processMetaExpression(const Expression& expression);
//
//  virtual TranscendResult process(const Expression& expression) override;
//};
//
//class TranscendFn: public compilation::Function<TranscendTag>{
//  typedef compilation::Function<TranscendTag> Parent;
//
//public:
//  TranscendFn(const ManagedFnPtr& fn, compilation::Target<TranscendTag>* target): Parent(fn, target){}
//  virtual TranscendResult process(const std::vector<TranscendResult>& args) override;
//};
//
//class TranscendTarget: public compilation::Target<TranscendTag>{
//public:
//  virtual void run() override;
//};

class TranscendPass;

class TranscendScope {
public:
  TranscendScope(const CodeScope* scope, const TranscendPass* pass): __pass(pass){}
  std::string compile(const Expression& e, std::list<std::string>& definitions);
  static void rule(std::ostringstream& output, const std::string& head, const std::list<std::string>& body);

private:
  const TranscendPass* __pass;
  std::string escapeVar(std::string&& var);
  std::string escapePredicate(std::string&& pred);

};

class TranscendPass: public AbstractPass<void>{
  typedef AbstractPass<void> Parent;

public:
  TranscendPass(PassManager* manager): Parent(manager){}
  void process(ManagedFnPtr function) override;
  void process(CodeScope* scope, PassContext context, const std::string &hintBlockDecl = "") override;
  void process(const Expression &expression, PassContext context, const std::string &varDecl = "") override;
  void finish() override;

private:
  std::map<const CodeScope*, TranscendScope*> __scopes;
  std::ostringstream __output;

  TranscendScope* getScope(const CodeScope * const scope);
  TranscendScope* getRootScope() {return getScope(0); }
};
}
#endif //XREATE_TRANSCENDTARGET_H
