#include "benchmark.h"
namespace NMiniBenchmark {
  static size_t bytesSize = 360;
  static size_t charsSize = 120;
  static std::string GenerateStringEnglish(){
    std::string s(bytesSize,' ');
    for(size_t i=0;i<charsSize;++i) s[i]='A';         // 1 byte
    return s;
  }
  static std::string GenerateStringEnglishQuater(){
    std::string s(bytesSize,' '); //360 bytes
    // only 30 out of 120 characters are filled
    for(size_t i=0;i<charsSize/4;++i) s[i]='A';
    return s;
  }
  static std::string GenerateStringEnglish40(){
    std::string s = GenerateStringEnglish();
    s[40]='B'; return s;
  }
  static std::string GenerateStringEnglishZ(){
    std::string s(bytesSize,' ');
    for(size_t i=0;i<charsSize;++i) s[i]='Z';         // 1 byte
    return s;
  }
  static std::string GenerateStringRussian(){
    std::string s(bytesSize,' '); std::string ya="Б"; // 2 bytes
    for(size_t i=0,j=0;i<charsSize;++i,j+=2) memcpy(&s[j], ya.data(), ya.size());
    return s;
  }
  static std::string GenerateStringRussian40(){
    std::string s = GenerateStringRussian(); std::string ya="Б"; // 2 bytes
    memcpy(&s[80], ya.data(), ya.size()); return s;
  }
  static std::string GenerateStringRussianZ(){
    std::string s(bytesSize,' '); std::string ya="Я"; // 2 bytes
    for(size_t i=0,j=0;i<charsSize;++i,j+=2) memcpy(&s[j], ya.data(), ya.size());
    return s;
  }
  static std::string GenerateStringChinese(){
    std::string s(bytesSize,' '); std::string ya="我"; // 3 bytes
    for(size_t i=0,j=0;i<charsSize;++i,j+=3) memcpy(&s[j], ya.data(), ya.size());
    return s;
  }
  static std::string GenerateStringChinese40(){
    std::string s = GenerateStringChinese(); std::string ya="是"; // 3 bytes
    memcpy(&s[120],ya.data(),ya.size()); return s;
  }

  static std::string GenerateStringChineseZ(){
    std::string s(bytesSize,' '); std::string ya="是"; // 3 bytes
    for(size_t i=0,j=0;i<charsSize;++i,j+=3) memcpy(&s[j], ya.data(), ya.size());
    return s;
  }

  static std::string _English = GenerateStringEnglish();
  static std::string _English40 = GenerateStringEnglish40();
  static std::string _EnglishQ = GenerateStringEnglishQuater();
  static std::string _Russian = GenerateStringRussian();
  static std::string _Russian40 = GenerateStringRussian40();
  static std::string _Chinese = GenerateStringChinese();
  static std::string _Chinese40 = GenerateStringChinese40();
  static std::string _EnglishZ = GenerateStringEnglishZ();
  static std::string _RussianZ = GenerateStringRussianZ();
  static std::string _ChineseZ = GenerateStringChineseZ();

  TEST(SkipTrailingSpaceImprovement,CHECK_SIZES){
    std::string yarus="Я";    // 2 bytes
    std::string yachina="我"; // 3 bytes
    ASSERT_EQ(yarus.size(),2u);
    ASSERT_EQ(yachina.size(),3u);
    ASSERT_EQ(skip_trailing_space((const uchar*)_Russian.data(),_Russian.size())-(const uchar*)_Russian.data(), 240u);
    ASSERT_EQ(skip_trailing_space((const uchar*)_Chinese.data(),_Chinese.size())-(const uchar*)_Chinese.data(), 360u);
  }

  #define STRNNCOLLSP(i1,i2) \
  void STRNNCOLLSP_##i1 ##i2(size_t iterations){ \
    for(size_t i=0;i<iterations;++i) \
      my_charset_utf8_general_ci.coll->strnncollsp(&my_charset_utf8_general_ci, \
        (const uchar*)i1.c_str(),i1.size(), \
        (const uchar*)i2.c_str(),i2.size(), \
        0); \
  } \
  BENCHMARK(STRNNCOLLSP_##i1 ##i2)


  STRNNCOLLSP(_EnglishQ,_EnglishQ)
  STRNNCOLLSP(_English,_English)
  STRNNCOLLSP(_English,_English40)
  STRNNCOLLSP(_English,_EnglishZ)
  STRNNCOLLSP(_Russian,_Russian)
  STRNNCOLLSP(_Russian,_Russian40)
  STRNNCOLLSP(_Russian,_RussianZ)
  STRNNCOLLSP(_Chinese,_Chinese)
  STRNNCOLLSP(_Chinese,_Chinese40)
  STRNNCOLLSP(_Chinese,_ChineseZ)
}