// 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 <fidl/flat_ast.h>
#include <fidl/lexer.h>
#include <fidl/names.h>
#include <fidl/parser.h>
#include <fidl/source_file.h>
#include <zircon/assert.h>

#include <algorithm>
#include <chrono>
#include <map>
#include <random>
#include <string>

#include <zxtest/zxtest.h>

#include "error_test.h"
#include "test_library.h"

#define DECL_NAME(D) static_cast<const std::string>(D->name.decl_name()).c_str()

#define ASSERT_DECL_NAME(D, N) ASSERT_STREQ(N, DECL_NAME(D));

#define ASSERT_MANGLED_DECL_NAME(D, N) ASSERT_SUBSTR(DECL_NAME(D), N);

#define ASSERT_DECL_FQ_NAME(D, N) ASSERT_STREQ(N, fidl::NameFlatName(D->name).c_str());

namespace {

// The calculated declaration order is a product of both the inter-type dependency relationships,
// and an ordering among the type names. To eliminate the effect of name ordering and exclusively
// test dependency ordering, this utility manufactures random names for the types tested.
class Namer {
 public:
  Namer() : vars_() {}

  std::string mangle(std::string input) {
    std::size_t start_pos = 0;
    std::size_t max_length = 0;
    while ((start_pos = input.find_first_of('#', start_pos)) != std::string::npos) {
      std::size_t end_pos = input.find_first_of('#', start_pos + 1);
      ZX_ASSERT(end_pos != std::string::npos);
      std::size_t key_len = end_pos - start_pos;
      max_length = std::max(max_length, key_len);
      start_pos = end_pos + 1;
    }
    std::size_t normalize_length = max_length + 5;
    while ((start_pos = input.find_first_of('#')) != std::string::npos) {
      std::size_t end_pos = input.find_first_of('#', start_pos + 1);
      auto key = input.substr(start_pos + 1, end_pos - start_pos - 1);
      if (vars_.find(key) == vars_.end()) {
        vars_[key] = random_prefix(key, normalize_length);
      }
      auto replacement = vars_.at(key);
      input.replace(start_pos, end_pos - start_pos + 1, replacement);
    }
    return input;
  }

  const char* of(std::string_view key) const { return vars_.find(key)->second.c_str(); }

 private:
  std::string random_prefix(std::string label, std::size_t up_to) {
    // normalize any name to at least |up_to| characters, by adding random prefix
    static std::string characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    constexpr size_t kSeed = 1337;
    static std::default_random_engine gen(kSeed);
    static std::uniform_int_distribution<size_t> distribution(0, characters.size() - 1);
    if (label.size() < up_to - 1) {
      label = "_" + label;
    }
    while (label.size() < up_to) {
      label.insert(0, 1, characters[distribution(gen)]);
    }
    return label;
  }

  // Use transparent comparator std::less<> to allow std::string_view lookups.
  std::map<std::string, std::string, std::less<>> vars_;
};

constexpr int kRepeatTestCount = 100;

// This test ensures that there are no unused anonymous structs in the
// declaration order output.
TEST(DeclarationOrderTest, GoodNoUnusedAnonymousNames) {
  for (int i = 0; i < kRepeatTestCount; i++) {
    Namer namer;
    auto source = namer.mangle(R"FIDL(
library example;

protocol #Protocol# {
    Method() -> ();
};

)FIDL");
    TestLibrary library(source);
    ASSERT_COMPILED(library);
    auto decl_order = library.declaration_order();
    ASSERT_EQ(1, decl_order.size());
    ASSERT_DECL_NAME(decl_order[0], namer.of("Protocol"));
  }
}

TEST(DeclarationOrderTest, GoodNonnullableRef) {
  for (int i = 0; i < kRepeatTestCount; i++) {
    Namer namer;
    auto source = namer.mangle(R"FIDL(
library example;

type #Request# = struct {
  req array<#Element#, 4>;
};

type #Element# = struct {};

protocol #Protocol# {
  SomeMethod(struct { req #Request#; });
};

)FIDL");
    TestLibrary library(source);
    ASSERT_COMPILED(library);
    auto decl_order = library.declaration_order();
    ASSERT_EQ(4, decl_order.size());
    ASSERT_DECL_NAME(decl_order[0], namer.of("Element"));
    ASSERT_DECL_NAME(decl_order[1], namer.of("Request"));
    ASSERT_MANGLED_DECL_NAME(decl_order[2], "ProtocolSomeMethodRequest");
    ASSERT_DECL_NAME(decl_order[3], namer.of("Protocol"));
  }
}

TEST(DeclarationOrderTest, GoodNullableRefBreaksDependency) {
  for (int i = 0; i < kRepeatTestCount; i++) {
    Namer namer;
    auto source = namer.mangle(R"FIDL(
library example;

type #Request# = resource struct {
  req array<box<#Element#>, 4>;
};

type #Element# = resource struct {
  prot client_end:#Protocol#;
};

protocol #Protocol# {
  SomeMethod(resource struct { req #Request#; });
};

)FIDL");
    TestLibrary library(source);
    ASSERT_COMPILED(library);
    auto decl_order = library.declaration_order();
    ASSERT_EQ(4, decl_order.size());

    // Since the Element struct contains a Protocol handle, it does not
    // have any dependencies, and we therefore have two independent
    // declaration sub-graphs:
    //   a. Element
    //   b. Request <- ProtocolSomeMethodRequest <- Protocol
    // Because of random prefixes, either (a) or (b) will be selected to
    // be first in the declaration order.
    bool element_is_first = strcmp(DECL_NAME(decl_order[0]), namer.of("Element")) == 0;

    if (element_is_first) {
      ASSERT_DECL_NAME(decl_order[0], namer.of("Element"));
      ASSERT_DECL_NAME(decl_order[1], namer.of("Request"));
      ASSERT_MANGLED_DECL_NAME(decl_order[2], "ProtocolSomeMethodRequest");
      ASSERT_DECL_NAME(decl_order[3], namer.of("Protocol"));
    } else {
      ASSERT_DECL_NAME(decl_order[0], namer.of("Request"));
      ASSERT_MANGLED_DECL_NAME(decl_order[1], "ProtocolSomeMethodRequest");
      ASSERT_DECL_NAME(decl_order[2], namer.of("Protocol"));
      ASSERT_DECL_NAME(decl_order[3], namer.of("Element"));
    }
  }
}

TEST(DeclarationOrderTest, GoodRequestTypeBreaksDependencyGraph) {
  for (int i = 0; i < kRepeatTestCount; i++) {
    Namer namer;
    auto source = namer.mangle(R"FIDL(
library example;

type #Request# = resource struct {
  req server_end:#Protocol#;
};

protocol #Protocol# {
  SomeMethod(resource struct { req #Request#; });
};

)FIDL");
    TestLibrary library(source);
    ASSERT_COMPILED(library);
    auto decl_order = library.declaration_order();
    ASSERT_EQ(3, decl_order.size());
    ASSERT_DECL_NAME(decl_order[0], namer.of("Request"));
    ASSERT_MANGLED_DECL_NAME(decl_order[1], "ProtocolSomeMethodRequest");
    ASSERT_DECL_NAME(decl_order[2], namer.of("Protocol"));
  }
}

TEST(DeclarationOrderTest, GoodNonnullableUnion) {
  for (int i = 0; i < kRepeatTestCount; i++) {
    Namer namer;
    auto source = namer.mangle(R"FIDL(
library example;

type #Xunion# = resource union {
  1: req server_end:#Protocol#;
  2: foo #Payload#;
};

protocol #Protocol# {
  SomeMethod(resource struct { req #Xunion#; });
};

type #Payload# = struct {
  a int32;
};

)FIDL");
    TestLibrary library(source);
    ASSERT_COMPILED(library);
    auto decl_order = library.declaration_order();
    ASSERT_EQ(4, decl_order.size());
    ASSERT_DECL_NAME(decl_order[0], namer.of("Payload"));
    ASSERT_DECL_NAME(decl_order[1], namer.of("Xunion"));
    ASSERT_MANGLED_DECL_NAME(decl_order[2], "ProtocolSomeMethodRequest");
    ASSERT_DECL_NAME(decl_order[3], namer.of("Protocol"));
  }
}

TEST(DeclarationOrderTest, GoodNullableUnion) {
  for (int i = 0; i < kRepeatTestCount; i++) {
    Namer namer;
    auto source = namer.mangle(R"FIDL(
library example;

type #Xunion# = resource union {
  1: req server_end:#Protocol#;
  2: foo #Payload#;
};

protocol #Protocol# {
  SomeMethod(resource struct { req #Xunion#:optional; });
};

type #Payload# = struct {
  a int32;
};

)FIDL");
    TestLibrary library(source);
    ASSERT_COMPILED(library);
    auto decl_order = library.declaration_order();
    ASSERT_EQ(4, decl_order.size());

    // Since the Xunion argument is nullable, Protocol does not have any
    // dependencies, and we therefore have two independent declaration
    // sub-graphs:
    //   a. Payload <- Xunion
    //   b. ProtocolSomeMethodRequest <- Protocol
    // Because of random prefixes, either (a) or (b) will be selected to
    // be first in the declaration order.
    bool payload_is_first = strcmp(DECL_NAME(decl_order[0]), namer.of("Payload")) == 0;
    if (payload_is_first) {
      ASSERT_DECL_NAME(decl_order[0], namer.of("Payload"));
      ASSERT_DECL_NAME(decl_order[1], namer.of("Xunion"));
      ASSERT_MANGLED_DECL_NAME(decl_order[2], "ProtocolSomeMethodRequest");
      ASSERT_DECL_NAME(decl_order[3], namer.of("Protocol"));
    } else {
      ASSERT_MANGLED_DECL_NAME(decl_order[0], "ProtocolSomeMethodRequest");
      ASSERT_DECL_NAME(decl_order[1], namer.of("Protocol"));
      ASSERT_DECL_NAME(decl_order[2], namer.of("Payload"));
      ASSERT_DECL_NAME(decl_order[3], namer.of("Xunion"));
    }
  }
}

TEST(DeclarationOrderTest, GoodNonnullableUnionInStruct) {
  for (int i = 0; i < kRepeatTestCount; i++) {
    Namer namer;
    auto source = namer.mangle(R"FIDL(
library example;

type #Payload# = struct {
  a int32;
};

protocol #Protocol# {
  SomeMethod(struct { req #Request#; });
};

type #Request# = struct {
  xu #Xunion#;
};

type #Xunion# = union {
  1: foo #Payload#;
};

)FIDL");
    TestLibrary library(source);
    ASSERT_COMPILED(library);
    auto decl_order = library.declaration_order();
    ASSERT_EQ(5, decl_order.size());
    ASSERT_DECL_NAME(decl_order[0], namer.of("Payload"));
    ASSERT_DECL_NAME(decl_order[1], namer.of("Xunion"));
    ASSERT_DECL_NAME(decl_order[2], namer.of("Request"));
    ASSERT_MANGLED_DECL_NAME(decl_order[3], "ProtocolSomeMethodRequest");
    ASSERT_DECL_NAME(decl_order[4], namer.of("Protocol"));
  }
}

TEST(DeclarationOrderTest, GoodNullableUnionInStruct) {
  for (int i = 0; i < kRepeatTestCount; i++) {
    Namer namer;
    auto source = namer.mangle(R"FIDL(
library example;

type #Payload# = struct {
  a int32;
};

protocol #Protocol# {
  SomeMethod(struct { req #Request#; });
};

type #Request# = struct {
  xu #Xunion#:optional;
};

type #Xunion# = union {
  1: foo #Payload#;
};

)FIDL");
    TestLibrary library(source);
    ASSERT_COMPILED(library);
    auto decl_order = library.declaration_order();
    ASSERT_EQ(5, decl_order.size());

    // Since the Xunion field is nullable, Request does not have any
    // dependencies, and we therefore have two independent declaration
    // sub-graphs:
    //   a. Payload <- Xunion
    //   b. Request <- ProtocolSomeMethodRequest <- Protocol
    // Because of random prefixes, either (a) or (b) will be selected to
    // be first in the declaration order.
    bool payload_is_first = strcmp(DECL_NAME(decl_order[0]), namer.of("Payload")) == 0;
    if (payload_is_first) {
      ASSERT_DECL_NAME(decl_order[0], namer.of("Payload"));
      ASSERT_DECL_NAME(decl_order[1], namer.of("Xunion"));
      ASSERT_DECL_NAME(decl_order[2], namer.of("Request"));
      ASSERT_MANGLED_DECL_NAME(decl_order[3], "ProtocolSomeMethodRequest");
      ASSERT_DECL_NAME(decl_order[4], namer.of("Protocol"));
    } else {
      ASSERT_DECL_NAME(decl_order[0], namer.of("Request"));
      ASSERT_MANGLED_DECL_NAME(decl_order[1], "ProtocolSomeMethodRequest");
      ASSERT_DECL_NAME(decl_order[2], namer.of("Protocol"));
      ASSERT_DECL_NAME(decl_order[3], namer.of("Payload"));
      ASSERT_DECL_NAME(decl_order[4], namer.of("Xunion"));
    }
  }
}

TEST(DeclarationOrderTest, GoodAllLibrariesOrderSingle) {
  for (int i = 0; i < kRepeatTestCount; i++) {
    Namer namer;
    auto source = namer.mangle(R"FIDL(
library example;

type #Foo# = struct {
  bar vector<#Bar#>;
};

type #Bar# = struct {};

)FIDL");
    TestLibrary library(source);
    ASSERT_COMPILED(library);
    ASSERT_EQ(library.declaration_order(), library.all_libraries_declaration_order());
  }
}

TEST(DeclarationOrderTest, GoodAllLibrariesOrderMultiple) {
  for (int i = 0; i < kRepeatTestCount; i++) {
    SharedAmongstLibraries shared;
    TestLibrary dependency(&shared, "dependency.fidl", R"FIDL(
library dependency;

type ExampleDecl1 = struct {};
)FIDL");
    ASSERT_COMPILED(dependency);

    TestLibrary library(&shared, "example.fidl", R"FIDL(
library example;

using dependency;

type ExampleDecl0 = struct {};
type ExampleDecl2 = struct {};

protocol ExampleDecl1 {
  Method(struct { arg dependency.ExampleDecl1; });
};

)FIDL");
    ASSERT_COMPILED(library);

    auto dependency_decl_order = dependency.declaration_order();
    ASSERT_EQ(1, dependency_decl_order.size());
    ASSERT_DECL_FQ_NAME(dependency_decl_order[0], "dependency/ExampleDecl1");

    auto library_decl_order = library.declaration_order();
    ASSERT_EQ(4, library_decl_order.size());
    ASSERT_DECL_FQ_NAME(library_decl_order[0], "example/ExampleDecl2");
    ASSERT_DECL_FQ_NAME(library_decl_order[1], "example/ExampleDecl1MethodRequest");
    ASSERT_DECL_FQ_NAME(library_decl_order[2], "example/ExampleDecl1");
    ASSERT_DECL_FQ_NAME(library_decl_order[3], "example/ExampleDecl0");

    auto all_decl_order = library.all_libraries_declaration_order();
    ASSERT_EQ(5, all_decl_order.size());
    ASSERT_DECL_FQ_NAME(all_decl_order[0], "dependency/ExampleDecl1");
    ASSERT_DECL_FQ_NAME(all_decl_order[1], "example/ExampleDecl2");
    ASSERT_DECL_FQ_NAME(all_decl_order[2], "example/ExampleDecl1MethodRequest");
    ASSERT_DECL_FQ_NAME(all_decl_order[3], "example/ExampleDecl1");
    ASSERT_DECL_FQ_NAME(all_decl_order[4], "example/ExampleDecl0");
  }
}

TEST(DeclarationOrderTest, GoodConstTypeComesFirst) {
  for (int i = 0; i < kRepeatTestCount; i++) {
    Namer namer;
    auto source = namer.mangle(R"FIDL(
library example;

const #Constant# #Alias# = 42;

alias #Alias# = uint32;

)FIDL");
    TestLibrary library(source);
    ASSERT_COMPILED(library);
    auto decl_order = library.declaration_order();
    ASSERT_EQ(2, decl_order.size());
    ASSERT_DECL_NAME(decl_order[0], namer.of("Alias"));
    ASSERT_DECL_NAME(decl_order[1], namer.of("Constant"));
  }
}

TEST(DeclarationOrderTest, GoodEnumOrdinalTypeComesFirst) {
  for (int i = 0; i < kRepeatTestCount; i++) {
    Namer namer;
    auto source = namer.mangle(R"FIDL(
library example;

type #Enum# = enum : #Alias# { A = 1; };

alias #Alias# = uint32;

)FIDL");
    TestLibrary library(source);
    ASSERT_COMPILED(library);
    auto decl_order = library.declaration_order();
    ASSERT_EQ(2, decl_order.size());
    ASSERT_DECL_NAME(decl_order[0], namer.of("Alias"));
    ASSERT_DECL_NAME(decl_order[1], namer.of("Enum"));
  }
}

TEST(DeclarationOrderTest, GoodBitsOrdinalTypeComesFirst) {
  for (int i = 0; i < kRepeatTestCount; i++) {
    Namer namer;
    auto source = namer.mangle(R"FIDL(
library example;

type #Bits# = bits : #Alias# { A = 1; };

alias #Alias# = uint32;

)FIDL");
    TestLibrary library(source);
    ASSERT_COMPILED(library);
    auto decl_order = library.declaration_order();
    ASSERT_EQ(2, decl_order.size());
    ASSERT_DECL_NAME(decl_order[0], namer.of("Alias"));
    ASSERT_DECL_NAME(decl_order[1], namer.of("Bits"));
  }
}

}  // namespace
