/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 "Session.h"

using namespace std;

Session* session;

void createTimeseries() {
  if (!session->checkTimeseriesExists("root.sg1.d1.s1")) {
    session->createTimeseries("root.sg1.d1.s1", TSDataType::BOOLEAN, TSEncoding::RLE,
                              CompressionType::SNAPPY);
  }
  if (!session->checkTimeseriesExists("root.sg1.d1.s2")) {
    session->createTimeseries("root.sg1.d1.s2", TSDataType::INT32, TSEncoding::RLE,
                              CompressionType::SNAPPY);
  }
  if (!session->checkTimeseriesExists("root.sg1.d1.s3")) {
    session->createTimeseries("root.sg1.d1.s3", TSDataType::FLOAT, TSEncoding::RLE,
                              CompressionType::SNAPPY);
  }

  // create timeseries with tags and attributes
  if (!session->checkTimeseriesExists("root.sg1.d1.s4")) {
    map<string, string> tags;
    tags["tag1"] = "v1";
    map<string, string> attributes;
    attributes["description"] = "v1";
    session->createTimeseries("root.sg1.d1.s4", TSDataType::INT64, TSEncoding::RLE,
                              CompressionType::SNAPPY, nullptr, &tags, &attributes, "temperature");
  }
}

void createMultiTimeseries() {
  if (!session->checkTimeseriesExists("root.sg1.d2.s1") &&
      !session->checkTimeseriesExists("root.sg1.d2.s2")) {
    vector<string> paths;
    paths.emplace_back("root.sg1.d2.s1");
    paths.emplace_back("root.sg1.d2.s2");
    vector<TSDataType::TSDataType> tsDataTypes;
    tsDataTypes.push_back(TSDataType::INT64);
    tsDataTypes.push_back(TSDataType::DOUBLE);
    vector<TSEncoding::TSEncoding> tsEncodings;
    tsEncodings.push_back(TSEncoding::RLE);
    tsEncodings.push_back(TSEncoding::RLE);
    vector<CompressionType::CompressionType> compressionTypes;
    compressionTypes.push_back(CompressionType::SNAPPY);
    compressionTypes.push_back(CompressionType::SNAPPY);

    vector<map<string, string>> tagsList;
    map<string, string> tags;
    tags["unit"] = "kg";
    tagsList.push_back(tags);
    tagsList.push_back(tags);

    vector<map<string, string>> attributesList;
    map<string, string> attributes;
    attributes["minValue"] = "1";
    attributes["maxValue"] = "100";
    attributesList.push_back(attributes);
    attributesList.push_back(attributes);

    vector<string> alias;
    alias.emplace_back("weight1");
    alias.emplace_back("weight2");

    session->createMultiTimeseries(paths, tsDataTypes, tsEncodings, compressionTypes, nullptr,
                                   &tagsList, &attributesList, &alias);
  }
}

void createSchemaTemplate() {
  if (!session->checkTemplateExists("template1")) {
    Template temp("template1", false);

    InternalNode iNodeD99("d99", false);

    MeasurementNode mNodeS1("s1", TSDataType::INT32, TSEncoding::RLE, CompressionType::SNAPPY);
    MeasurementNode mNodeS2("s2", TSDataType::INT64, TSEncoding::RLE, CompressionType::SNAPPY);
    MeasurementNode mNodeD99S1("s1", TSDataType::DOUBLE, TSEncoding::RLE, CompressionType::SNAPPY);
    MeasurementNode mNodeD99S2("s2", TSDataType::BOOLEAN, TSEncoding::RLE, CompressionType::SNAPPY);

    iNodeD99.addChild(mNodeD99S1);
    iNodeD99.addChild(mNodeD99S2);

    temp.addToTemplate(iNodeD99);
    temp.addToTemplate(mNodeS1);
    temp.addToTemplate(mNodeS2);

    session->createSchemaTemplate(temp);
    session->setSchemaTemplate("template1", "root.sg3.d1");
  }
}

void ActivateTemplate() {
  session->executeNonQueryStatement("insert into root.sg3.d1(timestamp,s1, s2) values(200, 1, 1);");
}

void showTimeseries() {
  unique_ptr<SessionDataSet> dataSet = session->executeQueryStatement("show timeseries");
  for (const string& name : dataSet->getColumnNames()) {
    cout << name << "  ";
  }
  cout << endl;

  dataSet->setFetchSize(1024);
  while (dataSet->hasNext()) {
    cout << dataSet->next()->toString();
  }
  cout << endl;

  dataSet->closeOperationHandle();
}

void insertRecord() {
  string deviceId = "root.sg2.d1";
  vector<string> measurements;
  measurements.emplace_back("s1");
  measurements.emplace_back("s2");
  measurements.emplace_back("s3");
  for (int64_t time = 0; time < 10; time++) {
    vector<string> values;
    values.emplace_back("1");
    values.emplace_back("2");
    values.emplace_back("3");
    session->insertRecord(deviceId, time, measurements, values);
  }
}

void insertTablet() {
  pair<string, TSDataType::TSDataType> pairA("s1", TSDataType::BOOLEAN);
  pair<string, TSDataType::TSDataType> pairB("s2", TSDataType::INT32);
  pair<string, TSDataType::TSDataType> pairC("s3", TSDataType::FLOAT);
  vector<pair<string, TSDataType::TSDataType>> schemas;
  schemas.push_back(pairA);
  schemas.push_back(pairB);
  schemas.push_back(pairC);

  Tablet tablet("root.sg1.d1", schemas, 100);

  for (int64_t time = 0; time < 30; time++) {
    size_t row = tablet.rowSize++;
    tablet.timestamps[row] = time;

    bool randVal1 = rand() % 2;
    tablet.addValue(0, row, randVal1);

    int randVal2 = rand();
    tablet.addValue(1, row, randVal2);

    float randVal3 = (float)(rand() / 99.9);
    tablet.addValue(2, row, randVal3);

    if (tablet.rowSize == tablet.maxRowNumber) {
      session->insertTablet(tablet, true);
      tablet.reset();
    }
  }

  if (tablet.rowSize != 0) {
    session->insertTablet(tablet);
    tablet.reset();
  }
}

void insertRecords() {
  string deviceId = "root.sg2.d1";
  vector<string> measurements;
  measurements.emplace_back("s1");
  measurements.emplace_back("s2");
  measurements.emplace_back("s3");

  vector<string> deviceIds;
  vector<vector<string>> measurementsList;
  vector<vector<string>> valuesList;
  vector<int64_t> timestamps;

  for (int64_t time = 10; time < 30; time++) {
    vector<string> values;
    values.emplace_back("1");
    values.emplace_back("2");
    values.emplace_back("3");

    deviceIds.push_back(deviceId);
    measurementsList.push_back(measurements);
    valuesList.push_back(values);
    timestamps.push_back(time);
    if (time != 20 && time % 10 == 0) {
      session->insertRecords(deviceIds, timestamps, measurementsList, valuesList);
      deviceIds.clear();
      measurementsList.clear();
      valuesList.clear();
      timestamps.clear();
    }
  }

  session->insertRecords(deviceIds, timestamps, measurementsList, valuesList);
}

void insertTablets() {
  pair<string, TSDataType::TSDataType> pairA("s1", TSDataType::INT64);
  pair<string, TSDataType::TSDataType> pairB("s2", TSDataType::DOUBLE);
  pair<string, TSDataType::TSDataType> pairC("s3", TSDataType::TEXT);
  vector<pair<string, TSDataType::TSDataType>> schemas;
  schemas.push_back(pairA);
  schemas.push_back(pairB);
  schemas.push_back(pairC);

  Tablet tablet1("root.sg1.d2", schemas, 100);
  Tablet tablet2("root.sg1.d3", schemas, 100);

  unordered_map<string, Tablet*> tabletMap;
  tabletMap["root.sg1.d2"] = &tablet1;
  tabletMap["root.sg1.d3"] = &tablet2;

  for (int64_t time = 0; time < 30; time++) {
    size_t row1 = tablet1.rowSize++;
    size_t row2 = tablet2.rowSize++;
    tablet1.timestamps[row1] = time;
    tablet2.timestamps[row2] = time;

    int64_t randVal11 = rand();
    tablet1.addValue(0, row1, randVal11);

    double randVal12 = rand() / 99.9;
    tablet1.addValue(1, row1, randVal12);

    string randVal13 = "string" + to_string(rand());
    tablet1.addValue(2, row1, randVal13);

    int64_t randVal21 = rand();
    tablet2.addValue(0, row2, randVal21);

    double randVal22 = rand() / 99.9;
    tablet2.addValue(1, row2, randVal22);

    string randVal23 = "string" + to_string(rand());
    tablet2.addValue(2, row2, randVal23);

    if (tablet1.rowSize == tablet1.maxRowNumber) {
      session->insertTablets(tabletMap, true);

      tablet1.reset();
      tablet2.reset();
    }
  }

  if (tablet1.rowSize != 0) {
    session->insertTablets(tabletMap, true);
    tablet1.reset();
    tablet2.reset();
  }
}

void insertTabletWithNullValues() {
  /*
     * A Tablet example:
     *      device1
     * time s1,   s2,   s3
     * 1,   null, 1,    1
     * 2,   2,    null, 2
     * 3,   3,    3,    null
     */
  pair<string, TSDataType::TSDataType> pairA("s1", TSDataType::INT64);
  pair<string, TSDataType::TSDataType> pairB("s2", TSDataType::INT64);
  pair<string, TSDataType::TSDataType> pairC("s3", TSDataType::INT64);
  vector<pair<string, TSDataType::TSDataType>> schemas;
  schemas.push_back(pairA);
  schemas.push_back(pairB);
  schemas.push_back(pairC);

  Tablet tablet("root.sg1.d4", schemas, 30);

  for (int64_t time = 0; time < 30; time++) {
    size_t row = tablet.rowSize++;
    tablet.timestamps[row] = time;
    for (int i = 0; i < 3; i++) {
      int64_t randVal = rand();
      tablet.addValue(i, row, randVal);
      // mark null value
      if (row % 3 == (unsigned int)i) {
        tablet.bitMaps[i].mark(row);
      }
    }
    if (tablet.rowSize == tablet.maxRowNumber) {
      session->insertTablet(tablet, true);
      tablet.reset();
    }
  }

  if (tablet.rowSize != 0) {
    session->insertTablet(tablet);
    tablet.reset();
  }
}

void nonQuery() {
  session->executeNonQueryStatement("insert into root.sg1.d1(timestamp,s1) values(100, 1);");
}

void query() {
  unique_ptr<SessionDataSet> dataSet =
      session->executeQueryStatement("select s1, s2, s3 from root.**");
  for (const string& name : dataSet->getColumnNames()) {
    cout << name << "  ";
  }
  cout << endl;

  dataSet->setFetchSize(1024);
  while (dataSet->hasNext()) {
    cout << dataSet->next()->toString();
  }
  cout << endl;

  dataSet->closeOperationHandle();
}

void deleteData() {
  string path = "root.sg1.d1.s1";
  int64_t deleteTime = 99;
  session->deleteData(path, deleteTime);
}

void deleteTimeseries() {
  vector<string> paths;
  vector<string> timeseriesGrp = {
      "root.sg1.d1.s1", "root.sg1.d1.s2", "root.sg1.d1.s3", "root.sg1.d2.s1", "root.sg1.d2.s2",
      "root.sg1.d2.s3", "root.sg1.d3.s1", "root.sg1.d3.s2", "root.sg1.d3.s3", "root.sg1.d4.s1",
      "root.sg1.d4.s2", "root.sg1.d4.s3", "root.sg2.d1.s1", "root.sg2.d1.s2", "root.sg2.d1.s3"};
  for (const string& timeseries : timeseriesGrp) {
    if (session->checkTimeseriesExists(timeseries)) {
      paths.push_back(timeseries);
    }
  }
  session->deleteTimeseries(paths);
}

void deleteStorageGroups() {
  vector<string> storageGroups;
  storageGroups.emplace_back("root.sg1");
  storageGroups.emplace_back("root.sg2");
  session->deleteStorageGroups(storageGroups);
}

void queryLast() {
  unique_ptr<SessionDataSet> dataSet =
      session->executeQueryStatement("select last s1,s2,s3 from root.**");
  for (const string& name : dataSet->getColumnNames()) {
    cout << name << "  ";
  }
  cout << endl;

  while (dataSet->hasNext()) {
    cout << dataSet->next()->toString();
  }
  cout << endl;

  dataSet->closeOperationHandle();
}

int main() {
  LOG_LEVEL = LEVEL_DEBUG;

  session = new Session("127.0.0.1", 6667, "root", "root");
  session->open(false);

  cout << "setStorageGroup: root.sg1\n" << endl;
  try {
    session->setStorageGroup("root.sg1");
  } catch (IoTDBException& e) {
    string errorMessage(e.what());
    if (errorMessage.find("StorageGroupAlreadySetException") == string::npos) {
      cout << errorMessage << endl;
    }
    //throw e;
  }

  cout << "setStorageGroup: root.sg2\n" << endl;
  try {
    session->setStorageGroup("root.sg2");
  } catch (IoTDBException& e) {
    string errorMessage(e.what());
    if (errorMessage.find("StorageGroupAlreadySetException") == string::npos) {
      cout << errorMessage << endl;
    }
    //throw e;
  }

  cout << "createTimeseries\n" << endl;
  createTimeseries();

  cout << "createMultiTimeseries\n" << endl;
  createMultiTimeseries();

  cout << "createSchemaTemplate\n" << endl;
  createSchemaTemplate();

  cout << "ActivateTemplate\n" << endl;
  ActivateTemplate();

  cout << "showTimeseries\n" << endl;
  showTimeseries();

  cout << "insertRecord\n" << endl;
  insertRecord();

  cout << "insertTablet\n" << endl;
  insertTablet();

  cout << "insertRecords\n" << endl;
  insertRecords();

  cout << "insertTablets\n" << endl;
  insertTablets();

  cout << "insertTabletWithNullValues\n" << endl;
  insertTabletWithNullValues();

  cout << "nonQuery\n" << endl;
  nonQuery();

  cout << "queryLast\n" << endl;
  queryLast();

  cout << "query\n" << endl;
  query();

  cout << "deleteData\n" << endl;
  deleteData();

  cout << "deleteTimeseries\n" << endl;
  deleteTimeseries();

  cout << "deleteStorageGroups\n" << endl;
  deleteStorageGroups();

  cout << "session close\n" << endl;
  session->close();

  delete session;

  cout << "finished!\n" << endl;
  return 0;
}
