// 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 "garnet/bin/run_test_component/test_metadata.h"

#include <string>
#include <utility>

#include <fuchsia/net/cpp/fidl.h>
#include <fuchsia/net/stack/cpp/fidl.h>
#include <fuchsia/netstack/cpp/fidl.h>
#include <fuchsia/sys/cpp/fidl.h>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "lib/fxl/files/directory.h"
#include "lib/fxl/files/file.h"
#include "lib/fxl/files/scoped_temp_dir.h"
#include "lib/fxl/strings/string_printf.h"
#include "lib/fxl/strings/substitute.h"

namespace run {
namespace {

using fuchsia::sys::LaunchInfo;

constexpr char kRequiredCmxElements[] = R"(
"program": {
  "binary": "path"
},
"sandbox": {
  "services": []
})";

class TestMetadataTest : public ::testing::Test {
 protected:
  void SetUp() override {
    ASSERT_NE("", tmp_dir_.path()) << "Cannot acccess /tmp";
  }

  void ExpectFailedParse(const std::string& json,
                         const std::string& expected_error) {
    std::string error;
    TestMetadata tm;
    EXPECT_FALSE(ParseFrom(&tm, json));
    EXPECT_TRUE(tm.HasError());
    EXPECT_THAT(tm.error_str(), ::testing::HasSubstr(expected_error));
  }

  bool ParseFrom(TestMetadata* tm, const std::string& json) {
    std::string json_path;
    if (!tmp_dir_.NewTempFileWithData(json, &json_path)) {
      return false;
    }
    const bool ret = tm->ParseFromFile(json_path);
    EXPECT_EQ(ret, !tm->HasError());
    return ret;
  }

  std::string CreateManifestJson(std::string additional_elements = "") {
    if (additional_elements == "") {
      return fxl::Substitute("{$0}", kRequiredCmxElements);
    } else {
      return fxl::Substitute("{$0, $1}", kRequiredCmxElements,
                             additional_elements);
    }
  }

 private:
  files::ScopedTempDir tmp_dir_;
};

TEST_F(TestMetadataTest, InvalidJson) {
  const std::string json = R"JSON({,,,})JSON";
  ExpectFailedParse(json, "Missing a name for object member.");
}

TEST_F(TestMetadataTest, NoFacet) {
  const std::string json = CreateManifestJson();
  TestMetadata tm;
  EXPECT_TRUE(ParseFrom(&tm, json));
  EXPECT_TRUE(tm.is_null());
}

TEST_F(TestMetadataTest, NoFuchsiaTestFacet) {
  const std::string json = CreateManifestJson(R"(
  "facets": {
  })");
  TestMetadata tm;
  EXPECT_TRUE(ParseFrom(&tm, json));
  EXPECT_TRUE(tm.is_null());
}

TEST_F(TestMetadataTest, NoServices) {
  const std::string json = CreateManifestJson(R"(
  "facets": {
    "fuchsia.test": {
    }
  })");
  TestMetadata tm;
  EXPECT_TRUE(ParseFrom(&tm, json));
  EXPECT_FALSE(tm.is_null());
  ASSERT_FALSE(tm.HasServices());
}

TEST_F(TestMetadataTest, InvalidTestFacet) {
  const std::string json = CreateManifestJson(R"(
  "facets": {
    "fuchsia.test": [
    ]
  })");
  ExpectFailedParse(json, "'fuchsia.test' in 'facets' should be an object.");
}

TEST_F(TestMetadataTest, InvalidServicesType) {
  const std::string json = CreateManifestJson(R"(
  "facets": {
    "fuchsia.test": {
      "injected-services": []
    }
  })");
  ExpectFailedParse(json,
                    "'injected-services' in 'fuchsia.test' should be an "
                    "object.");
}

TEST_F(TestMetadataTest, InvalidSystemServicesType) {
  std::string json = CreateManifestJson(R"(
  "facets": {
    "fuchsia.test": {
      "system-services": "string"
    }
  })");
  auto expected_error =
      "'system-services' in 'fuchsia.test' should be a string array.";
  ExpectFailedParse(json, expected_error);

  json = CreateManifestJson(R"(
  "facets": {
    "fuchsia.test": {
      "system-services": {}
    }
  })");
  ExpectFailedParse(json, expected_error);

  json = CreateManifestJson(R"(
  "facets": {
    "fuchsia.test": {
      "system-services": [ 2, 3 ]
    }
  })");
  ExpectFailedParse(json, expected_error);

  json = CreateManifestJson(R"(
  "facets": {
    "fuchsia.test": {
      "system-services": [ "fuchsia.netstack.Netstack", "invalid_service" ]
    }
  })");
  ExpectFailedParse(json,
                    "'system-services' cannot contain 'invalid_service'.");
}

TEST_F(TestMetadataTest, InvalidServices) {
  std::string json = CreateManifestJson(R"(
  "facets": {
    "fuchsia.test": {
      "injected-services": {
        1: "url"
      }
    }
  })");
  ExpectFailedParse(json, "Missing a name for object member.");

  json = CreateManifestJson(R"(
  "facets": {
    "fuchsia.test": {
      "injected-services": {
        "1": 2
      }
    }
  })");
  ExpectFailedParse(json,
                    "'1' must be a string or a non-empty array of strings.");
  json = CreateManifestJson(R"(
  "facets": {
    "fuchsia.test": {
      "injected-services": {
        "1": [2]
      }
    }
  })");

  ExpectFailedParse(json,
                    "'1' must be a string or a non-empty array of strings.");
}

TEST_F(TestMetadataTest, EmptyServices) {
  std::string json = CreateManifestJson(R"(
  "facets": {
    "fuchsia.test": {
      "injected-services": {
      }
    }
  })");
  TestMetadata tm;
  EXPECT_TRUE(ParseFrom(&tm, json));
  EXPECT_FALSE(tm.HasError());
  EXPECT_FALSE(tm.HasServices());
}

std::pair<std::string, LaunchInfo> create_pair(const std::string& s1,
                                               LaunchInfo launch_info) {
  return std::make_pair(s1, std::move(launch_info));
}

TEST_F(TestMetadataTest, ValidServices) {
  std::string json = CreateManifestJson(R"(
  "facets": {
    "fuchsia.test": {
      "injected-services": {
        "1": "url1",
        "2": ["url2", "--a=b", "c"],
        "3": "url3"
      }
    }
  })");

  TestMetadata tm;
  EXPECT_TRUE(ParseFrom(&tm, json));
  auto services = tm.TakeServices();
  ASSERT_EQ(3u, services.size());
  EXPECT_EQ(services[0], create_pair("1", LaunchInfo{.url = "url1"}));
  LaunchInfo launch_info{.url = "url2"};
  launch_info.arguments.push_back("--a=b");
  launch_info.arguments.push_back("c");
  EXPECT_EQ(services[1], create_pair("2", std::move(launch_info)));
  EXPECT_EQ(services[2], create_pair("3", LaunchInfo{.url = "url3"}));
  EXPECT_EQ(tm.system_services().size(), 0u);
}

TEST_F(TestMetadataTest, ValidSystemServices) {
  std::string json = CreateManifestJson(R"(
  "facets": {
    "fuchsia.test": {
      "system-services": [
        "fuchsia.net.Connectivity",
        "fuchsia.net.SocketProvider",
        "fuchsia.net.stack.Stack",
        "fuchsia.netstack.Netstack"
      ]
    }
  })");

  {
    TestMetadata tm;
    EXPECT_TRUE(ParseFrom(&tm, json));
    EXPECT_EQ(tm.system_services().size(), 4u);
    EXPECT_THAT(tm.system_services(),
                ::testing::ElementsAre(fuchsia::net::Connectivity::Name_,
                                       fuchsia::net::SocketProvider::Name_,
                                       fuchsia::net::stack::Stack::Name_,
                                       fuchsia::netstack::Netstack::Name_));
  }

  json = CreateManifestJson(R"(
  "facets": {
    "fuchsia.test": {
      "system-services": [
        "fuchsia.net.Connectivity",
        "fuchsia.net.SocketProvider",
        "fuchsia.netstack.Netstack"
      ]
    }
  })");
  {
    TestMetadata tm;
    EXPECT_TRUE(ParseFrom(&tm, json));
    EXPECT_EQ(tm.system_services().size(), 3u);
    EXPECT_THAT(tm.system_services(),
                ::testing::ElementsAre(fuchsia::net::Connectivity::Name_,
                                       fuchsia::net::SocketProvider::Name_,
                                       fuchsia::netstack::Netstack::Name_));
  }
}

}  // namespace
}  // namespace run
