/*
 * Copyright 2012, The Android Open Source Project
 *
 * 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.
 */

#include <sys/stat.h>

#include <cstdarg>
#include <cctype>

#include <algorithm>
#include <sstream>
#include <string>
#include <utility>

#include "os_sep.h"
#include "slang_rs_context.h"
#include "slang_rs_export_var.h"
#include "slang_rs_export_foreach.h"
#include "slang_rs_export_func.h"
#include "slang_rs_reflect_utils.h"
#include "slang_version.h"
#include "slang_utils.h"

#include "slang_rs_reflection_base.h"



using namespace std;

namespace slang {

static const char *const gApacheLicenseNote =
"/*\n"
" * Copyright (C) 2012 The Android Open Source Project\n"
" *\n"
" * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
" * you may not use this file except in compliance with the License.\n"
" * You may obtain a copy of the License at\n"
" *\n"
" *      http://www.apache.org/licenses/LICENSE-2.0\n"
" *\n"
" * Unless required by applicable law or agreed to in writing, software\n"
" * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
" * See the License for the specific language governing permissions and\n"
" * limitations under the License.\n"
" */\n"
"\n";


RSReflectionBase::RSReflectionBase(const RSContext *con)
  : mVerbose(true) {
  mRSContext = con;
  mLicenseNote = gApacheLicenseNote;

}

RSReflectionBase::~RSReflectionBase() {

}

/*
bool RSReflectionBase::openFile(const string &name, string &errorMsg) {
    if(!mUseStdout) {
        mOF.clear();
        if(!SlangUtils::CreateDirectoryWithParents(mOutputPath, &errorMsg)) {
            return false;
        }

        string cf(mOutputPath + OS_PATH_SEPARATOR_STR + name);
        mOF.open(cf.c_str());
        if(!mOF.good()) {
            errorMsg = "failed to open file '" + cf + "' for write";
            return false;
        }
    }
    return true;
}
*/

void RSReflectionBase::startFile(const string &filename) {
  if(mVerbose) {
    printf("Generating %s\n", filename.c_str());
  }

  // License
  write(mLicenseNote);

  // Notice of generated file
  write("/*");
  write(" * This file is auto-generated. DO NOT MODIFY!");
  write(" * The source Renderscript file: " + mInputFileName);
  write(" */");
  write("");
}

// remove path plus .rs from filename to generate class name
string RSReflectionBase::stripRS(const string &s) const {
  string tmp(s);
  size_t pos = tmp.rfind(".rs");
  if(pos != string::npos) {
    tmp.erase(pos);
  }
  pos = tmp.rfind("/");
  if (pos != string::npos) {
    tmp.erase(0, pos+1);
  }
  return tmp;
}

void RSReflectionBase::write(const std::string &t) {
  //printf("%s%s\n", mIndent.c_str(), t.c_str());
  mText.push_back(mIndent + t);
}

void RSReflectionBase::write(const std::stringstream &t) {
  mText.push_back(mIndent + t.str());
}


void RSReflectionBase::incIndent() {
  mIndent.append("    ");
}

void RSReflectionBase::decIndent() {
  mIndent.erase(0, 4);
}

bool RSReflectionBase::writeFile(const string &filename, const vector< string > &txt) {
  FILE *pfin = fopen((mOutputPath + filename).c_str(), "wt");
  if (pfin == NULL) {
    fprintf(stderr, "Error: could not write file %s\n", filename.c_str());
    return false;
  }

  for(size_t ct=0; ct < txt.size(); ct++) {
    fprintf(pfin, "%s\n", txt[ct].c_str());
  }
  fclose(pfin);
  return true;
}


string RSReflectionBase::genInitValue(const clang::APValue &Val, bool asBool) {
  stringstream tmp;
  switch (Val.getKind()) {
    case clang::APValue::Int: {
      llvm::APInt api = Val.getInt();
      if(asBool) {
        tmp << ((api.getSExtValue() == 0) ? "false" : "true");
      } else {
        tmp << api.getSExtValue();
        if (api.getBitWidth() > 32) {
          tmp << "L";
        }
      }
      break;
    }

    case clang::APValue::Float: {
      llvm::APFloat apf = Val.getFloat();
      if (&apf.getSemantics() == &llvm::APFloat::IEEEsingle) {
        tmp << apf.convertToFloat() << "f";
      } else {
        tmp << apf.convertToDouble();
      }
      break;
    }

    case clang::APValue::ComplexInt:
    case clang::APValue::ComplexFloat:
    case clang::APValue::LValue:
    case clang::APValue::Vector: {
      slangAssert(false && "Primitive type cannot have such kind of initializer");
      break;
    }

    default: {
      slangAssert(false && "Unknown kind of initializer");
    }
  }
  return tmp.str();
}


}
