// 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 <cstdlib>
#include <cstdio>
#include <iostream>
#include <vector>
#include <boost/scoped_ptr.hpp>

#include "common/init.h"
#include "exec/row-batch-list.h"
#include "runtime/descriptors.h"
#include "runtime/mem-pool.h"
#include "runtime/mem-tracker.h"
#include "runtime/string-value.h"
#include "runtime/tuple-row.h"
#include "service/fe-support.h"
#include "service/frontend.h"
#include "util/runtime-profile-counters.h"
#include "testutil/desc-tbl-builder.h"
#include "testutil/gtest-util.h"

#include "common/names.h"

using namespace impala;

namespace impala {

// For computing tuple mem layouts.
scoped_ptr<Frontend> fe;

class RowBatchListTest : public testing::Test {
 public:
  RowBatchListTest() {}

 protected:
  MemTracker tracker_;
  ObjectPool pool_;
  RowDescriptor* desc_;

  virtual void SetUp() {
    DescriptorTblBuilder builder(fe.get(), &pool_);
    builder.DeclareTuple() << TYPE_INT;
    DescriptorTbl* desc_tbl = builder.Build();
    vector<bool> nullable_tuples(1, false);
    vector<TTupleId> tuple_id(1, (TTupleId) 0);
    desc_ = pool_.Add(new RowDescriptor(*desc_tbl, tuple_id, nullable_tuples));
  }

  RowBatch* CreateRowBatch(int start, int end) {
    int num_rows = end - start + 1;
    RowBatch* batch = pool_.Add(new RowBatch(desc_, num_rows, &tracker_));
    int32_t* tuple_mem = reinterpret_cast<int32_t*>(
        batch->tuple_data_pool()->Allocate(sizeof(int32_t) * num_rows));

    for (int i = start; i <= end; ++i) {
      int idx = batch->AddRow();
      TupleRow* row = batch->GetRow(idx);
      *tuple_mem = i;
      row->SetTuple(0, reinterpret_cast<Tuple*>(tuple_mem));

      batch->CommitLastRow();
      tuple_mem++;
    }
    return batch;
  }

  // Validate that row contains the expected value
  void ValidateMatch(TupleRow* row, int32_t expected) {
    EXPECT_EQ(expected, *reinterpret_cast<int32_t*>(row->GetTuple(0)));
  }

  void FullScan(RowBatchList* list, int start, int end) {
    EXPECT_LT(start, end);
    RowBatchList::TupleRowIterator it = list->Iterator();
    int i = start;
    while (!it.AtEnd()) {
      EXPECT_TRUE(it.GetRow() != NULL);
      ValidateMatch(it.GetRow(), i);
      it.Next();
      ++i;
    }
    EXPECT_EQ(end, i - 1);
  }
};

// This tests inserts the rows [0->5] to list. It validates that they are all there.
TEST_F(RowBatchListTest, BasicTest) {
  RowBatchList row_list;
  RowBatch* batch = CreateRowBatch(0, 5);
  row_list.AddRowBatch(batch);
  EXPECT_EQ(row_list.total_num_rows(), 6);

  // Do a full table scan and validate returned pointers
  FullScan(&row_list, 0, 5);
}

// This tests an empty batch is handled correctly.
TEST_F(RowBatchListTest, EmptyBatchTest) {
  const int ALLOC_SIZE = 128;
  RowBatchList row_list;
  RowBatch* batch1 = pool_.Add(new RowBatch(desc_, 1, &tracker_));
  batch1->tuple_data_pool()->Allocate(ALLOC_SIZE);
  DCHECK_EQ(ALLOC_SIZE, batch1->tuple_data_pool()->total_allocated_bytes());

  row_list.AddRowBatch(batch1);
  EXPECT_EQ(row_list.total_num_rows(), 0);
  RowBatchList::TupleRowIterator it = row_list.Iterator();
  EXPECT_TRUE(it.AtEnd());

  // IMPALA-4049: list should transfer resources attached to empty batch.
  RowBatch* batch2 = pool_.Add(new RowBatch(desc_, 1, &tracker_));
  DCHECK_EQ(0, batch2->tuple_data_pool()->total_allocated_bytes());
  row_list.TransferResourceOwnership(batch2);
  DCHECK_EQ(0, batch1->tuple_data_pool()->total_allocated_bytes());
  DCHECK_EQ(ALLOC_SIZE, batch2->tuple_data_pool()->total_allocated_bytes());
}

// This tests inserts 100 row batches of 1024 rows each to list.  It validates that they
// are all there.
TEST_F(RowBatchListTest, MultipleRowBatchesTest) {
  RowBatchList row_list;

  int BATCH_SIZE = 1024;
  for (int batch_idx = 0; batch_idx < 100; ++batch_idx) {
    int batch_start = batch_idx * BATCH_SIZE;
    int batch_end = batch_start + BATCH_SIZE - 1;
    RowBatch* batch = CreateRowBatch(batch_start, batch_end);
    row_list.AddRowBatch(batch);
    EXPECT_EQ(row_list.total_num_rows(), batch_end + 1);
    FullScan(&row_list, 0, batch_end);
  }
}

}

int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
  InitCommonRuntime(argc, argv, true, impala::TestInfo::BE_TEST);
  InitFeSupport();
  fe.reset(new Frontend());
  return RUN_ALL_TESTS();
}
