// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "mist/config_loader.h"

#include <string>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <gtest/gtest.h>

#include "mist/proto_bindings/config.pb.h"
#include "mist/proto_bindings/usb_modem_info.pb.h"

using base::FilePath;
using std::string;

namespace mist {

namespace {

const char kTestConfigFileContent[] =
    "# Test config\n"
    "\n"
    "# USB modem 1\n"
    "usb_modem_info {\n"
    "  initial_usb_id {\n"
    "    vendor_id: 0x2345\n"
    "    product_id: 0x7890\n"
    "  }\n"
    "}\n"
    "# USB modem 2\n"
    "usb_modem_info {\n"
    "  initial_usb_id { vendor_id: 0x1234 product_id: 0xabcd }\n"
    "  final_usb_id { vendor_id: 0x5678 product_id: 0xfedc }\n"
    "  final_usb_id { vendor_id: 0x3210 product_id: 0x9876 }\n"
    "  usb_message: \"0123456789abcdef\"\n"
    "  usb_message: \"fedcba9877654210\"\n"
    "  usb_message: \"1234\"\n"
    "  expect_response: true\n"
    "  initial_delay_ms: 2500\n"
    "}\n";

}  // namespace

class ConfigLoaderTest : public testing::Test {
 protected:
  bool CreateConfigFileInDir(const string& content,
                             const FilePath& dir,
                             FilePath* config_file) {
    if (!base::CreateTemporaryFileInDir(dir, config_file))
      return false;

    if (base::WriteFile(*config_file, content.data(), content.size()) !=
        static_cast<int>(content.size())) {
      return false;
    }

    return true;
  }

  ConfigLoader config_loader_;
  base::ScopedTempDir temp_dir_;
};

TEST_F(ConfigLoaderTest, GetUsbModemInfo) {
  // No config is loaded.
  EXPECT_EQ(nullptr, config_loader_.GetUsbModemInfo(0x1111, 0x2222));

  base::FilePath config_file;
  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
  ASSERT_TRUE(CreateConfigFileInDir(kTestConfigFileContent, temp_dir_.GetPath(),
                                    &config_file));

  EXPECT_TRUE(config_loader_.LoadConfig(config_file));

  EXPECT_EQ(nullptr, config_loader_.GetUsbModemInfo(0x1111, 0x2222));

  const UsbModemInfo* usb_modem_info1 =
      config_loader_.GetUsbModemInfo(0x2345, 0x7890);
  EXPECT_NE(nullptr, usb_modem_info1);
  EXPECT_EQ(0x2345, usb_modem_info1->initial_usb_id().vendor_id());
  EXPECT_EQ(0x7890, usb_modem_info1->initial_usb_id().product_id());
  EXPECT_EQ(0, usb_modem_info1->final_usb_id_size());
  EXPECT_EQ(0, usb_modem_info1->usb_message_size());
  EXPECT_FALSE(usb_modem_info1->expect_response());
  EXPECT_EQ(0, usb_modem_info1->initial_delay_ms());

  const UsbModemInfo* usb_modem_info2 =
      config_loader_.GetUsbModemInfo(0x1234, 0xabcd);
  EXPECT_NE(nullptr, usb_modem_info2);
  EXPECT_EQ(0x1234, usb_modem_info2->initial_usb_id().vendor_id());
  EXPECT_EQ(0xabcd, usb_modem_info2->initial_usb_id().product_id());
  EXPECT_EQ(2, usb_modem_info2->final_usb_id_size());
  EXPECT_EQ(0x5678, usb_modem_info2->final_usb_id(0).vendor_id());
  EXPECT_EQ(0xfedc, usb_modem_info2->final_usb_id(0).product_id());
  EXPECT_EQ(0x3210, usb_modem_info2->final_usb_id(1).vendor_id());
  EXPECT_EQ(0x9876, usb_modem_info2->final_usb_id(1).product_id());
  EXPECT_EQ(3, usb_modem_info2->usb_message_size());
  EXPECT_EQ("0123456789abcdef", usb_modem_info2->usb_message(0));
  EXPECT_EQ("fedcba9877654210", usb_modem_info2->usb_message(1));
  EXPECT_EQ("1234", usb_modem_info2->usb_message(2));
  EXPECT_TRUE(usb_modem_info2->expect_response());
  EXPECT_EQ(2500, usb_modem_info2->initial_delay_ms());
}

TEST_F(ConfigLoaderTest, LoadEmptyConfigFile) {
  base::FilePath config_file;
  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
  ASSERT_TRUE(CreateConfigFileInDir("", temp_dir_.GetPath(), &config_file));

  EXPECT_TRUE(config_loader_.LoadConfig(config_file));
  Config* config = config_loader_.config_.get();
  EXPECT_NE(nullptr, config);
  EXPECT_EQ(0, config->usb_modem_info_size());
}

TEST_F(ConfigLoaderTest, LoadInvalidConfigFile) {
  base::FilePath config_file;
  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
  ASSERT_TRUE(CreateConfigFileInDir("<invalid config>", temp_dir_.GetPath(),
                                    &config_file));

  EXPECT_FALSE(config_loader_.LoadConfig(config_file));
  EXPECT_EQ(nullptr, config_loader_.config_.get());
}

TEST_F(ConfigLoaderTest, LoadNonExistentConfigFile) {
  EXPECT_FALSE(config_loader_.LoadConfig(FilePath("/non-existent-file")));
  EXPECT_EQ(nullptr, config_loader_.config_.get());
}

TEST_F(ConfigLoaderTest, LoadValidConfigFile) {
  base::FilePath config_file;
  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
  ASSERT_TRUE(CreateConfigFileInDir(kTestConfigFileContent, temp_dir_.GetPath(),
                                    &config_file));

  EXPECT_TRUE(config_loader_.LoadConfig(config_file));
  Config* config = config_loader_.config_.get();
  EXPECT_NE(nullptr, config);
  EXPECT_EQ(2, config->usb_modem_info_size());

  const UsbModemInfo& usb_modem_info1 = config->usb_modem_info(0);
  EXPECT_EQ(0x2345, usb_modem_info1.initial_usb_id().vendor_id());
  EXPECT_EQ(0x7890, usb_modem_info1.initial_usb_id().product_id());

  const UsbModemInfo& usb_modem_info2 = config->usb_modem_info(1);
  EXPECT_EQ(0x1234, usb_modem_info2.initial_usb_id().vendor_id());
  EXPECT_EQ(0xabcd, usb_modem_info2.initial_usb_id().product_id());
}

}  // namespace mist
