#include "osixaka.h"
#include <akaxiso/schema/schema.h>
#include "xschemaparser.h"
#include "generator.h"

namespace {
  std::string get_dirpath(const std::string &path) {
    std::string::size_type pos = path.find_last_of("/\\");
    if (pos == std::string::npos) { // not found!
      return "./";
    }      
    else {
      return path.substr(0, pos + 1);
    }
  }
}


void osixaka::initialize() {
  aka::xmlns("aka", "http://akaxiso.sourceforge.jp/akaxiso2");
  aka::xmlns("std", "http://akaxiso.sourceforge.jp/osixaka/c++-std");
  aka::xmlns("osp", "http://akaxiso.sourceforge.jp/osixaka/preference");
  xs::instantiate_xiso();
  registry::register_ns();
}


int osixaka::parse(const std::string &filepath) {
  xschemaparser parser(ostm_, verbose_, do_dump_);
  dirpath_ = get_dirpath(filepath);
  target_schema_ = aka::shared_ptr<xs::schema>(parser.parse(filepath));
  return target_schema_.get() == 0 ? 1 : 0;
}

int osixaka::process() {
  try {
    processor prc(registry_, dirpath_, ostm_, verbose_);
    prc.preprocess(*target_schema_);
    prc.process(*target_schema_);
    return 0;
  }
  catch (const std::exception &e) {
    ostm_ << e.what() << std::endl;
    ostm_ << "Failed to generate files. Aborting..." << std::endl;
    return 1;
  }
  catch ( ... ) {
    ostm_ << "Unknown exception caught. Aborting..." << std::endl;
    return 1;
  }
}  


void osixaka::generate(const std::string &outputdir) {
  generator gen(std::cerr, outputdir);
  gen.generate(registry_);
}

void osixaka::akaxisonize() {
  akaxisonizer_.replace_any();
  akaxisonizer_.akaxisonize();
  akaxisonizer_.add_missings();
}
