// Copyright 2018 The Fuchsia 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 "src/lib/cmx/facet_parser/cmx_facet_parser.h"

#include <fcntl.h>

#include <string>
#include <tuple>

#include <gtest/gtest.h>

#include "rapidjson/document.h"
#include "src/lib/files/scoped_temp_dir.h"
#include "src/lib/json_parser/json_parser.h"

namespace component {
namespace {

class CmxFacetParserTest : public ::testing::Test {
 protected:
  // Returns true for a valid cmx manifest represented by |json|.
  bool ParseFrom(const std::string& json) {
    json::JSONParser json_parser;
    rapidjson::Document document = json_parser.ParseFromString(json, "test_file");
    EXPECT_FALSE(json_parser.HasError());

    EXPECT_TRUE(facet_parser().Parse(document, &json_parser));
    return !json_parser.HasError();
  }

  bool ParseFromFileAt(const std::string& json) {
    files::ScopedTempDir tmp_dir;
    const int dirfd = open(tmp_dir.path().c_str(), O_RDONLY);

    std::string tmp_file;
    tmp_dir.NewTempFileWithData(json, &tmp_file);

    json::JSONParser json_parser;
    return facet_parser().ParseFromFileAt(dirfd, tmp_file, &json_parser);
  }

  CmxFacetParser& facet_parser() { return facet_parser_; };

 private:
  CmxFacetParser facet_parser_;
};

TEST_F(CmxFacetParserTest, ParseEmpty) { EXPECT_TRUE(ParseFrom(R"JSON({})JSON")); }

TEST_F(CmxFacetParserTest, ParseSection) {
  EXPECT_TRUE(ParseFrom(R"JSON({"facets":
      {"section1":
        { "v1" : 1, "v2" : 2, "v3": "v3_value" },
      "section2": "some_str"}
    })JSON"));

  const auto& section1 = facet_parser().GetSection("section1");
  ASSERT_FALSE(section1.IsNull());
  ASSERT_TRUE(section1.HasMember("v1"));
  ASSERT_TRUE(section1.HasMember("v2"));
  ASSERT_TRUE(section1.HasMember("v3"));
  EXPECT_EQ(section1["v1"].GetInt(), 1);
  EXPECT_EQ(section1["v2"].GetInt(), 2);
  EXPECT_EQ(std::string(section1["v3"].GetString()), "v3_value");

  const auto& section2 = facet_parser().GetSection("section2");
  ASSERT_FALSE(section2.IsNull());
  ASSERT_TRUE(section2.IsString());
  EXPECT_EQ(std::string(section2.GetString()), "some_str");

  const auto& invalid = facet_parser().GetSection("invalid");
  ASSERT_TRUE(invalid.IsNull());
}

TEST_F(CmxFacetParserTest, ParseFromFileAt) {
  files::ScopedTempDir tmp_dir;
  const int dirfd = open(tmp_dir.path().c_str(), O_RDONLY);

  std::string tmp_file;
  tmp_dir.NewTempFileWithData(R"JSON({"facets":
      {"section1":
        { "v1" : 1, "v2" : 2, "v3": "v3_value" },
      "section2": "some_str"}
    })JSON",
                              &tmp_file);

  json::JSONParser json_parser;
  EXPECT_TRUE(facet_parser().ParseFromFileAt(dirfd, tmp_file, &json_parser));
  EXPECT_FALSE(json_parser.HasError());
}

}  // namespace
}  // namespace component
