/**
 * 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 "query_optimizer/tests/ExecutionGeneratorTestRunner.hpp"

#include <cstdio>
#include <memory>
#include <set>
#include <string>

#include "cli/DropRelation.hpp"
#include "cli/PrintToScreen.hpp"
#include "parser/ParseStatement.hpp"
#include "query_execution/ForemanSingleNode.hpp"
#include "query_execution/QueryExecutionUtil.hpp"
#include "query_optimizer/Optimizer.hpp"
#include "query_optimizer/OptimizerContext.hpp"
#include "query_optimizer/QueryHandle.hpp"
#include "utility/MemStream.hpp"
#include "utility/SqlError.hpp"

#include "glog/logging.h"

namespace quickstep {

class CatalogRelation;

namespace optimizer {

const std::string ExecutionGeneratorTestRunner::kResetOption =
    "reset_before_execution";

void ExecutionGeneratorTestRunner::runTestCase(
    const std::string &input, const std::set<std::string> &options,
    std::string *output) {
  // TODO(qzeng): Test multi-threaded query execution when we have a Sort operator.

  VLOG(4) << "Test SQL(s): " << input;

  if (options.find(kResetOption) != options.end()) {
    test_database_loader_.clear();
    test_database_loader_.createTestRelation(false /* allow_vchar */);
    test_database_loader_.loadTestRelation();
  }

  MemStream output_stream;
  sql_parser_.feedNextBuffer(new std::string(input));

  // Redirect stderr to output_stream.
  if (!FLAGS_logtostderr) {
    stderr = output_stream.file();
  }

  while (true) {
    ParseResult result = sql_parser_.getNextStatement();
    if (result.condition != ParseResult::kSuccess) {
      if (result.condition == ParseResult::kError) {
        *output = result.error_message;
      }
      break;
    } else {
      const ParseStatement &parse_statement = *result.parsed_statement;
      const CatalogRelation *query_result_relation = nullptr;
      try {
        OptimizerContext optimizer_context;
        auto query_handle = std::make_unique<QueryHandle>(0 /* query_id */, main_thread_client_id_);

        optimizer_.generateQueryHandle(parse_statement,
                                       test_database_loader_.catalog_database(),
                                       &optimizer_context,
                                       query_handle.get());
        query_result_relation = query_handle->getQueryResultRelation();

        QueryExecutionUtil::ConstructAndSendAdmitRequestMessage(
            main_thread_client_id_,
            foreman_->getBusClientID(),
            query_handle.release(),
            &bus_);
      } catch (const SqlError &error) {
        *output = error.formatMessage(input);
        break;
      }

      QueryExecutionUtil::ReceiveQueryCompletionMessage(
          main_thread_client_id_, &bus_);

      if (query_result_relation) {
        PrintToScreen::PrintRelation(*query_result_relation,
                                     test_database_loader_.storage_manager(),
                                     output_stream.file());
        DropRelation::Drop(*query_result_relation,
                           test_database_loader_.catalog_database(),
                           test_database_loader_.storage_manager());
      }
    }
  }

  if (output->empty()) {
    *output = output_stream.str();
  }
}

}  // namespace optimizer
}  // namespace quickstep
