/*
 * 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;

#define DEFAULT_ROW_NUMBER 1000000

void createAlignedTimeseries() {
    string alignedDeviceId = "root.sg1.d1";
    vector<string> measurements = {"s1", "s2", "s3"};
    vector<string> alignedTimeseries = {"root.sg1.d1.s1", "root.sg1.d1.s2", "root.sg1.d1.s3"};
    vector<TSDataType::TSDataType> dataTypes = {TSDataType::INT32, TSDataType::DOUBLE, TSDataType::BOOLEAN};
    vector<TSEncoding::TSEncoding> encodings = {TSEncoding::PLAIN, TSEncoding::GORILLA, TSEncoding::RLE};
    vector<CompressionType::CompressionType> compressors = {
            CompressionType::SNAPPY, CompressionType::UNCOMPRESSED, CompressionType::SNAPPY};
    for (const string &timeseries: alignedTimeseries) {
        if (session->checkTimeseriesExists(timeseries)) {
            session->deleteTimeseries(timeseries);
        }
    }
    session->createAlignedTimeseries(alignedDeviceId, measurements, dataTypes, encodings, compressors);
}

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

        InternalNode iNodeD99("d99", true);

        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 showDevices() {
    unique_ptr<SessionDataSet> dataSet = session->executeQueryStatement("show devices with database");
    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 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 insertAlignedRecord() {
    string deviceId = "root.sg1.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("1.0");
        values.emplace_back("true");
        session->insertAlignedRecord(deviceId, time, measurements, values);
    }
}

void insertAlignedRecords() {
    string deviceId = "root.sg1.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 < 20; time++) {
        vector<string> values;
        values.emplace_back("1");
        values.emplace_back("1.0");
        values.emplace_back("true");

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

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

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

    Tablet tablet("root.sg2.d2", schemas, 100000);
    tablet.setAligned(true);

    for (int64_t time = 0; time < DEFAULT_ROW_NUMBER; time++) {
        size_t row = tablet.rowSize++;
        tablet.timestamps[row] = time;
        int randVal1 = 123456;
        double randVal2 = 123456.1234;
        double randVal3 = 123456.1234;
        tablet.addValue(0, row, &randVal1);
        tablet.addValue(1, row, &randVal2);
        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 insertAlignedTablets() {
    pair<string, TSDataType::TSDataType> pairA("s1", TSDataType::INT32);
    pair<string, TSDataType::TSDataType> pairB("s2", TSDataType::DOUBLE);
    pair<string, TSDataType::TSDataType> pairC("s3", TSDataType::BOOLEAN);
    vector<pair<string, TSDataType::TSDataType>> schemas;
    schemas.push_back(pairA);
    schemas.push_back(pairB);
    schemas.push_back(pairC);

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

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

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

        int randVal11 = rand();
        int randVal12 = rand();
        int randVal13 = rand();
        tablet1.addValue(0, row1, &randVal11);
        tablet2.addValue(0, row2, &randVal12);
        tablet3.addValue(0, row3, &randVal13);

        double randVal21 = rand() / 99.9;
        double randVal22 = rand() / 99.9;
        double randVal23 = rand() / 99.9;
        tablet1.addValue(1, row1, &randVal21);
        tablet2.addValue(1, row2, &randVal22);
        tablet3.addValue(1, row3, &randVal23);

        bool randVal31 = (bool)(rand() % 2);
        bool randVal32 = (bool)(rand() % 2);
        bool randVal33 = (bool)(rand() % 2);
        tablet1.addValue(2, row1, &randVal31);
        tablet2.addValue(2, row2, &randVal32);
        tablet3.addValue(2, row3, &randVal33);

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

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

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

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

    Tablet tablet("root.sg1.d4", schemas, 20);
    tablet.setAligned(true);

    for (int64_t time = 0; time < 20; time++) {
        size_t row = tablet.rowSize++;
        tablet.timestamps[row] = time;
        for (int i = 0; i < 3; i++) {
            int randVal1 = rand();
            int64_t randVal2 = rand();
            bool randVal3 = (bool)(rand() % 2);
            if (i == 0) {
                tablet.addValue(i, row, &randVal1);
            } else if (i == 1) {
                tablet.addValue(i, row, &randVal2);
            } else {
                tablet.addValue(i, row, &randVal3);
            }
            // 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 query() {
    unique_ptr<SessionDataSet> dataSet = session->executeQueryStatement("select * from root.sg1.**");
    cout << "timestamp" << "  ";
    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.**";
    int64_t deleteTime = 49;
    session->deleteData(path, deleteTime);
}

void deleteTimeseries() {
    vector<string> paths;
    vector<string> alignedTimeseries = {"root.sg1.d1.s1", "root.sg1.d1.s2", "root.sg1.d1.s3", "root.sg1.d1.s4",
                                        "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.d2.s1", "root.sg2.d2.s2", "root.sg2.d2.s3", };
    for (const string &timeseries: alignedTimeseries) {
        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);
}


int main() {
    LOG_LEVEL = LEVEL_DEBUG;

    session = new Session("127.0.0.1", 6667, "root", "root");

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

    cout << "setStorageGroup\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 << "createAlignedTimeseries\n" << endl;
    createAlignedTimeseries();

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

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

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

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

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

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

    cout << "insertAlignedTablet" << endl;
    cout << "Insert " << DEFAULT_ROW_NUMBER << " records." << endl;
    time_t now1 = time(0);
    insertAlignedTablet();
    time_t now2 = time(0);
    time_t useTime = now2 - now1;
    cout << "Use time: " << useTime << "s.\n" << endl;

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

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

    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;
}
