// 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 <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <vector>
#include <sstream>
#include "runtime/string-value.h"
#include "util/benchmark.h"
#include "util/cpu-info.h"
#include "util/string-parser.h"

#include "common/names.h"

using namespace impala;

// Machine Info: Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz
// atod:                 Function     Rate (iters/ms)          Comparison
//----------------------------------------------------------------------
//               Impala Decimal4                84.6                  1X
//               Impala Decimal8               49.77             0.5883X
//              Impala Decimal16               17.08             0.2019X

template <typename Decimal>
struct TestData {
  int precision;
  int scale;
  double probability_negative;
  vector<StringValue> data;
  vector<string> memory;
  vector<Decimal> result;
};

double Rand() {
  return rand() / static_cast<double>(RAND_MAX);
}

template <typename Decimal>
void AddTestData(TestData<Decimal>* data, const string& input) {
  data->memory.push_back(input);
  const string& str = data->memory.back();
  data->data.push_back(StringValue(const_cast<char*>(str.c_str()), str.length()));
}

template <typename Decimal>
void AddTestData(TestData<Decimal>* data, int n) {
  int128_t max_whole = data->precision > data->scale ?
      DecimalUtil::GetScaleMultiplier<int128_t>(data->precision - data->scale) - 1 : 0;
  int128_t max_fraction = data->scale > 0 ?
      DecimalUtil::GetScaleMultiplier<int128_t>(data->scale) - 1 : 0;
  for (int i = 0; i < n; ++i) {
    stringstream ss;
    if (data->probability_negative > Rand()) ss << "-";
    if (max_whole > 0) ss << static_cast<int128_t>(max_whole * Rand());
    if (max_fraction > 0) ss << "." << static_cast<int128_t>(max_fraction * Rand());
    AddTestData(data, ss.str());
  }
}

template <typename Decimal, typename Storage>
void TestImpala(int batch_size, void* d) {
  TestData<Decimal>* data = reinterpret_cast<TestData<Decimal>*>(d);
  ColumnType column_type = ColumnType::CreateDecimalType(data->precision, data->scale);
  Decimal val;
  for (int i = 0; i < batch_size; ++i) {
    int n = data->data.size();
    for (int j = 0; j < n; ++j) {
      const StringValue& str = data->data[j];
      StringParser::ParseResult dummy;
      val = StringParser::StringToDecimal<Storage>(
          str.ptr, str.len, column_type, false, &dummy);
      data->result[j] = val;
    }
  }
}

int main(int argc, char **argv) {
  CpuInfo::Init();
  cout << Benchmark::GetMachineInfo() << endl;

  Benchmark suite("atod");

  TestData<Decimal4Value> data4;
  data4.precision = ColumnType::MAX_DECIMAL4_PRECISION;
  data4.scale = data4.precision / 2;
  data4.probability_negative = 0.25;
  AddTestData(&data4, 1000);
  data4.result.resize(data4.data.size());
  suite.AddBenchmark("Impala Decimal4", TestImpala<Decimal4Value, int32_t>, &data4);

  TestData<Decimal8Value> data8;
  data8.precision = ColumnType::MAX_DECIMAL8_PRECISION;
  data8.scale = data8.precision / 2;
  data8.probability_negative = 0.25;
  AddTestData(&data8, 1000);
  data8.result.resize(data8.data.size());
  suite.AddBenchmark("Impala Decimal8", TestImpala<Decimal8Value, int64_t>, &data8);

  TestData<Decimal16Value> data16;
  data16.precision = ColumnType::MAX_PRECISION;
  data16.scale = data16.precision / 2;
  data16.probability_negative = 0.25;
  AddTestData(&data16, 1000);
  data16.result.resize(data16.data.size());
  suite.AddBenchmark("Impala Decimal16", TestImpala<Decimal16Value, int128_t>, &data16);

  cout << suite.Measure();
  return 0;
}
