/*
 * Copyright (C) 2018 The Android Open Source Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
#pragma once
#include <gtest/gtest.h>

#include "fastboot_driver.h"

#include "extensions.h"
#include "usb_transport_sniffer.h"

namespace fastboot {

const int USB_TIMEOUT = 30000;

constexpr char USB_PORT_GONE[] =
        "The USB port has disappeared, this is usually due to the bootloader crashing";

class FastBootTest : public testing::Test {
  public:
    static int serial_port;
    static std::string device_serial;
    static constexpr int MAX_USB_TRIES = 10;

    static int MatchFastboot(usb_ifc_info* info, const std::string& local_serial = "");
    bool UsbStillAvailible();
    bool UserSpaceFastboot();
    void ReconnectFastbootDevice();

  protected:
    RetCode DownloadCommand(uint32_t size, std::string* response = nullptr,
                            std::vector<std::string>* info = nullptr);

    RetCode SendBuffer(const std::vector<char>& buf);
    RetCode HandleResponse(std::string* response = nullptr,
                           std::vector<std::string>* info = nullptr, int* dsize = nullptr);

    void SetUp() override;
    void TearDown() override;
    void TearDownSerial();
    void SetLockState(bool unlock, bool assert_change = true);

    std::unique_ptr<UsbTransportSniffer> transport;
    std::unique_ptr<FastBootDriver> fb;

  private:
    // This is an annoying hack
    static std::string cb_scratch;
    static std::string device_path;
    static std::string initial_slot;
};

template <bool UNLOCKED>
class ModeTest : public FastBootTest {
  protected:
    void SetUp() override;
};

class Fuzz : public ModeTest<true> {
  protected:
    void TearDown() override;
};

// These derived classes without overrides serve no purpose other than to allow gtest to name them
// differently
class BasicFunctionality : public ModeTest<true> {};
class Conformance : public ModeTest<true> {};
class LogicalPartitionCompliance : public ModeTest<true> {};
class UnlockPermissions : public ModeTest<true> {};
class LockPermissions : public ModeTest<false> {};

// Magic C++ double inheritance
class ExtensionsGetVarConformance
    : public ModeTest<true>,
      public ::testing::WithParamInterface<
              std::pair<std::string, extension::Configuration::GetVar>> {};

class ExtensionsOemConformance
    : public ModeTest<true>,
      public ::testing::WithParamInterface<
              std::tuple<std::string, bool, extension::Configuration::CommandTest>> {};

class ExtensionsPackedValid
    : public ModeTest<true>,
      public ::testing::WithParamInterface<
              std::pair<std::string, extension::Configuration::PackedInfoTest>> {};

class ExtensionsPackedInvalid
    : public ModeTest<true>,
      public ::testing::WithParamInterface<
              std::pair<std::string, extension::Configuration::PackedInfoTest>> {};

template <bool UNLOCKED>
class ExtensionsPartition
    : public FastBootTest,
      public ::testing::WithParamInterface<
              std::pair<std::string, extension::Configuration::PartitionInfo>> {
  protected:
    void SetUp() override;
    int64_t part_size;
    int64_t max_flash;
    int64_t max_dl;
    std::vector<std::string> real_parts;  // includes the slots
};

class AnyPartition : public ExtensionsPartition<true> {};
class WriteablePartition : public ExtensionsPartition<true> {};
class WriteHashablePartition : public ExtensionsPartition<true> {};
class WriteHashNonParsedPartition : public ExtensionsPartition<true> {};

class FuzzWriteablePartition : public ExtensionsPartition<true> {};
class FuzzWriteableParsedPartition : public ExtensionsPartition<true> {};
class FuzzAnyPartitionLocked : public ExtensionsPartition<false> {};

class UserdataPartition : public ExtensionsPartition<true> {};

class SparseTestPartition : public ExtensionsPartition<true> {};

}  // end namespace fastboot
