/*
 * Copyright 2015 Facebook, Inc.
 *
 * Licensed 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.
 */

/**
 * This file is supposed to be included from within
 * FBStringTest. Do not use otherwise.
 *
 * override-include-guard
 */

void BENCHFUN(initRNG)(size_t iters, size_t) {
  srand(seed);
}
BENCHMARK_PARAM(BENCHFUN(initRNG), 0);

void BENCHFUN(defaultCtor)(size_t iters, size_t) {
  FOR_EACH_RANGE (i, 0, iters) {
    STRING s[4096];
    doNotOptimizeAway(&s);
  }
}
BENCHMARK_PARAM(BENCHFUN(defaultCtor), 0);

void BENCHFUN(copyCtor)(size_t iters, size_t arg) {
  STRING s;
  BENCHMARK_SUSPEND {
    randomString(&s, arg);
  }
  FOR_EACH_RANGE (i, 0, iters) {
    STRING s1 = s;
    doNotOptimizeAway(&s1);
  }
}
BENCHMARK_PARAM(BENCHFUN(copyCtor), 32768);

void BENCHFUN(ctorFromArray)(size_t iters, size_t arg) {
  STRING s;
  BENCHMARK_SUSPEND {
    randomString(&s, arg);
    if (s.empty()) {
      s = "This is rare.";
    }
  }
  FOR_EACH_RANGE (i, 0, iters) {
    STRING s1(s.data(), s.size());
    doNotOptimizeAway(&s1);
  }
}
BENCHMARK_PARAM(BENCHFUN(ctorFromArray), 32768);

void BENCHFUN(ctorFromTwoPointers)(size_t iters, size_t arg) {
  static STRING s;
  BENCHMARK_SUSPEND {
    if (s.size() < arg) s.resize(arg);
  }
  FOR_EACH_RANGE (i, 0, iters) {
    STRING s1(s.begin(), s.end());
    doNotOptimizeAway(&s1);
  }
}
BENCHMARK_PARAM(BENCHFUN(ctorFromTwoPointers), 0);
BENCHMARK_PARAM(BENCHFUN(ctorFromTwoPointers), 7);
BENCHMARK_PARAM(BENCHFUN(ctorFromTwoPointers), 15);
BENCHMARK_PARAM(BENCHFUN(ctorFromTwoPointers), 23);
BENCHMARK_PARAM(BENCHFUN(ctorFromTwoPointers), 24);

void BENCHFUN(ctorFromChar)(size_t iters, size_t arg) {
  FOR_EACH_RANGE (i, 0, iters) {
    STRING s1('a', arg);
    doNotOptimizeAway(&s1);
  }
}
BENCHMARK_PARAM(BENCHFUN(ctorFromChar), 1048576);

void BENCHFUN(assignmentOp)(size_t iters, size_t arg) {
  STRING s;
  BENCHMARK_SUSPEND {
    randomString(&s, arg);
  }
  FOR_EACH_RANGE (i, 0, iters) {
    STRING s1;
    BENCHMARK_SUSPEND {
      randomString(&s1, arg);
      doNotOptimizeAway(&s1);
    }
    s1 = s;
  }
}
BENCHMARK_PARAM(BENCHFUN(assignmentOp), 256);

void BENCHFUN(assignmentFill)(size_t iters, size_t) {
  STRING s;
  FOR_EACH_RANGE (i, 0, iters) {
    s = static_cast<char>(i);
    doNotOptimizeAway(&s);
  }
}
BENCHMARK_PARAM(BENCHFUN(assignmentFill), 0);

void BENCHFUN(resize)(size_t iters, size_t arg) {
  STRING s;
  FOR_EACH_RANGE (i, 0, iters) {
    s.resize(random(0, arg));
    doNotOptimizeAway(&s);
  }
}
BENCHMARK_PARAM(BENCHFUN(resize), 524288);

void BENCHFUN(findSuccessful)(size_t iters, size_t arg) {
  size_t pos, len;
  STRING s;

  BENCHMARK_SUSPEND {

    // Text courtesy (ahem) of
    // http://www.psychologytoday.com/blog/career-transitions/200906/
    // the-dreaded-writing-sample
    s = "\
Even if you've mastered the art of the cover letter and the resume, \
another part of the job search process can trip up an otherwise \
qualified candidate: the writing sample.\n\
\n\
Strong writing and communication skills are highly sought after by \
most employers. Whether crafting short emails or lengthy annual \
reports, many workers use their writing skills every day. And for an \
employer seeking proof behind that ubiquitous candidate \
phrase,\"excellent communication skills\", a required writing sample \
is invaluable.\n\
\n\
Writing samples need the same care and attention given to cover \
letters and resumes. Candidates with otherwise impeccable credentials \
are routinely eliminated by a poorly chosen writing sample. Notice I \
said \"poorly chosen\" not \"poorly written.\" Because that's the rub: \
a writing sample not only reveals the individual's writing skills, it \
also offers a peek into what they consider important or relevant for \
the position. If you miss that mark with your writing sample, don't \
expect to get a call for an interview.";

    pos = random(0, s.size());
    len = random(0, s.size() - pos);
  }
  FOR_EACH_RANGE (i, 0, iters) {
    doNotOptimizeAway(s.find(s.data(), pos, len));
  }
}
BENCHMARK_PARAM(BENCHFUN(findSuccessful), 524288);

void BENCHFUN(findUnsuccessful)(size_t iters, size_t arg) {
  STRING s, s1;

  BENCHMARK_SUSPEND {
    s = "\
Even if you've mastered the art of the cover letter and the resume, \
another part of the job search process can trip up an otherwise \
qualified candidate: the writing sample.\n\
\n\
Strong writing and communication skills are highly sought after by \
most employers. Whether crafting short emails or lengthy annual \
reports, many workers use their writing skills every day. And for an \
employer seeking proof behind that ubiquitous candidate \
phrase,\"excellent communication skills\", a required writing sample \
is invaluable.\n\
\n\
Writing samples need the same care and attention given to cover \
letters and resumes. Candidates with otherwise impeccable credentials \
are routinely eliminated by a poorly chosen writing sample. Notice I \
said \"poorly chosen\" not \"poorly written.\" Because that's the rub: \
a writing sample not only reveals the individual's writing skills, it \
also offers a peek into what they consider important or relevant for \
the position. If you miss that mark with your writing sample, don't \
expect to get a call for an interview.";

    s1 = "So how do you tackle that writing sample request?";
  }

  FOR_EACH_RANGE (i, 0, iters) {
    doNotOptimizeAway(s.find(s1));
  }
}
BENCHMARK_PARAM(BENCHFUN(findUnsuccessful), 524288);

void BENCHFUN(equality)(size_t iters, size_t arg) {
  std::vector<STRING> haystack(arg);

  BENCHMARK_SUSPEND {
    for (auto& hay : haystack) {
      randomBinaryString(&hay, 1024);
    }
  }

  FOR_EACH_RANGE (i, 0, iters) {
    STRING needle;
    randomBinaryString(&needle, 1024);
    doNotOptimizeAway(std::find(haystack.begin(), haystack.end(), needle));
  }
}
BENCHMARK_PARAM(BENCHFUN(equality), 65536);

void BENCHFUN(replace)(size_t iters, size_t arg) {
  STRING s;
  BENCHMARK_SUSPEND {
    randomString(&s, arg);
  }
  FOR_EACH_RANGE (i, 0, iters) {
    BenchmarkSuspender susp;
    doNotOptimizeAway(&s);
    auto const pos = random(0, s.size());
    auto toRemove = random(0, s.size() - pos);
    auto toInsert = random(0, arg);
    STRING s1;
    randomString(&s1, toInsert);
    susp.dismiss();

   s.replace(pos, toRemove, s1);
  }
}
BENCHMARK_PARAM(BENCHFUN(replace), 256);

void BENCHFUN(push_back)(size_t iters, size_t arg) {
  FOR_EACH_RANGE (i, 0, iters) {
    STRING s;
    FOR_EACH_RANGE (j, 0, arg) {
      s += ' ';
    }
  }
}
BENCHMARK_PARAM(BENCHFUN(push_back), 1);
BENCHMARK_PARAM(BENCHFUN(push_back), 23);
BENCHMARK_PARAM(BENCHFUN(push_back), 127);
BENCHMARK_PARAM(BENCHFUN(push_back), 1024);

void BENCHFUN(short_append)(size_t iters, size_t arg) {
  FOR_EACH_RANGE (i, 0, iters) {
    STRING s;
    FOR_EACH_RANGE (j, 0, arg) {
      s += "012";
    }
  }
}
BENCHMARK_PARAM(BENCHFUN(short_append), 23);
BENCHMARK_PARAM(BENCHFUN(short_append), 1024);
