/*
 * Copyright 2020 The Android Open Source Project
 *
 * 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.
 */

#pragma once

#include <unistd.h>

#include <unordered_map>

#include "base/logging.h"  // LOG() stdout and android log
#include "include/hardware/bluetooth.h"
#include "test/headless/bt_stack_info.h"
#include "test/headless/get_options.h"
#include "test/headless/log.h"

extern bt_interface_t bluetoothInterface;

namespace bluetooth {
namespace test {
namespace headless {

template <typename T>
using ExecutionUnit = std::function<T()>;

constexpr char kHeadlessInitialSentinel[] =
    " INITIAL HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS";
constexpr char kHeadlessStartSentinel[] =
    " START HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS";
constexpr char kHeadlessStopSentinel[] =
    " STOP HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS";
constexpr char kHeadlessFinalSentinel[] =
    " FINAL HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS";

class HeadlessStack {
 protected:
  HeadlessStack(const char** stack_init_flags)
      : stack_init_flags_(stack_init_flags) {}
  virtual ~HeadlessStack() = default;

  void SetUp();
  void TearDown();

  const char** StackInitFlags() const { return stack_init_flags_; }

 private:
  const char** stack_init_flags_;
  std::unique_ptr<BtStackInfo> bt_stack_info_;
};

class HeadlessRun : public HeadlessStack {
 protected:
  const bluetooth::test::headless::GetOpt& options_;
  unsigned long loop_{0};

  HeadlessRun(const bluetooth::test::headless::GetOpt& options)
      : HeadlessStack(options.StackInitFlags()), options_(options) {}

  template <typename T>
  T RunOnHeadlessStack(ExecutionUnit<T> func) {
    LOG(INFO) << kHeadlessInitialSentinel;
    SetUp();
    LOG(INFO) << kHeadlessStartSentinel;

    T rc;
    for (loop_ = 0; loop_ < options_.loop_; loop_++) {
      LOG_CONSOLE("Loop started: %lu", loop_);
      rc = func();
      if (options_.msec_ != 0) {
        usleep(options_.msec_ * 1000);
      }
      if (rc) {
        break;
      }
      LOG_CONSOLE("Loop completed: %lu", loop_);
    }
    if (rc) {
      LOG(ERROR) << "FAIL:" << rc << " loop/loops:" << loop_ << "/"
                 << options_.loop_;
    } else {
      LOG(INFO) << "PASS:" << rc << " loop/loops:" << loop_ << "/"
                << options_.loop_;
    }

    LOG(INFO) << kHeadlessStopSentinel;
    TearDown();
    LOG(INFO) << kHeadlessFinalSentinel;
    return rc;
  }
  virtual ~HeadlessRun() = default;
};

template <typename T>
class HeadlessTest : public HeadlessRun {
 public:
  virtual T Run() {
    if (options_.non_options_.size() == 0) {
      fprintf(stdout, "Must supply at least one subtest name\n");
      return -1;
    }

    std::string subtest = options_.GetNextSubTest();
    if (test_nodes_.find(subtest) == test_nodes_.end()) {
      fprintf(stdout, "Unknown subtest module:%s\n", subtest.c_str());
      return -1;
    }
    return test_nodes_.at(subtest)->Run();
  }

  virtual ~HeadlessTest() = default;

 protected:
  HeadlessTest(const bluetooth::test::headless::GetOpt& options)
      : HeadlessRun(options) {}

  std::unordered_map<std::string, std::unique_ptr<HeadlessTest<T>>> test_nodes_;
};

}  // namespace headless
}  // namespace test
}  // namespace bluetooth
