// Copyright 2020 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/developer/forensics/feedback/annotations/data_register.h"

#include <fuchsia/feedback/cpp/fidl.h>
#include <lib/syslog/cpp/macros.h>

#include <limits>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "src/developer/forensics/feedback/annotations/annotation_manager.h"
#include "src/developer/forensics/testing/unit_test_fixture.h"
#include "src/lib/files/file.h"
#include "src/lib/files/path.h"
#include "src/lib/files/scoped_temp_dir.h"

namespace forensics::feedback {
namespace {

using fuchsia::feedback::ComponentData;
using testing::Pair;
using testing::UnorderedElementsAreArray;

constexpr char kReservedNamespace[] = "reserved-namespace";

class DataRegisterTest : public UnitTestFixture {
 public:
  DataRegisterTest() { MakeNewDataRegister(); }

 protected:
  void Upsert(ComponentData data) {
    bool called_back = false;
    data_register_->Upsert(std::move(data), [&called_back]() { called_back = true; });
    RunLoopUntilIdle();
    FX_CHECK(called_back);
  }

  std::string RegisterJsonPath() { return files::JoinPath(tmp_dir_.path(), "register.json"); }

  std::string ReadRegisterJson() {
    std::string json;
    files::ReadFileToString(RegisterJsonPath(), &json);
    return json;
  }

  void MakeNewDataRegister(const size_t max_size = std::numeric_limits<size_t>::max()) {
    data_register_ = std::make_unique<DataRegister>(
        max_size, std::set<std::string>({kReservedNamespace}), RegisterJsonPath());
  }

  files::ScopedTempDir tmp_dir_;
  std::unique_ptr<DataRegister> data_register_;
};

TEST_F(DataRegisterTest, Upsert_Basic) {
  ComponentData data;
  data.set_namespace_("namespace");
  data.set_annotations({
      {"k", "v"},
  });

  Upsert(std::move(data));

  EXPECT_THAT(data_register_->Get(), UnorderedElementsAreArray({
                                         Pair("namespace.k", "v"),
                                     }));
  EXPECT_FALSE(data_register_->IsMissingAnnotations());
  EXPECT_EQ(ReadRegisterJson(), R"({
    "namespace": {
        "k": "v"
    }
})");
}

TEST_F(DataRegisterTest, Upsert_DefaultNamespaceIfNoNamespaceProvided) {
  ComponentData data;
  data.set_annotations({
      {"k", "v"},
  });

  Upsert(std::move(data));

  EXPECT_THAT(data_register_->Get(), UnorderedElementsAreArray({
                                         Pair("misc.k", "v"),
                                     }));
  EXPECT_FALSE(data_register_->IsMissingAnnotations());
  EXPECT_EQ(ReadRegisterJson(), R"({
    "misc": {
        "k": "v"
    }
})");
}

TEST_F(DataRegisterTest, Upsert_NoInsertionsOnEmptyAnnotations) {
  ComponentData data;

  Upsert(std::move(data));

  EXPECT_THAT(data_register_->Get(), testing::IsEmpty());
  EXPECT_FALSE(data_register_->IsMissingAnnotations());
  EXPECT_TRUE(ReadRegisterJson().empty());
}

TEST_F(DataRegisterTest, Upsert_NoInsertionsOnReservedNamespace) {
  ComponentData data;
  data.set_namespace_(kReservedNamespace);
  data.set_annotations({
      {"k", "v"},
  });

  Upsert(std::move(data));

  EXPECT_THAT(data_register_->Get(), testing::IsEmpty());
  EXPECT_FALSE(data_register_->IsMissingAnnotations());
  EXPECT_FALSE(data_register_->IsMissingAnnotations());
  EXPECT_TRUE(ReadRegisterJson().empty());
}

TEST_F(DataRegisterTest, Upsert_NoInsertionsOnTooMany) {
  MakeNewDataRegister(/*max_size=*/1);
  ComponentData data;
  data.set_namespace_("namespace");
  data.set_annotations({
      {"k", "v"},
  });

  Upsert(std::move(data));

  EXPECT_THAT(data_register_->Get(), UnorderedElementsAreArray({
                                         Pair("namespace.k", "v"),
                                     }));
  EXPECT_FALSE(data_register_->IsMissingAnnotations());
  EXPECT_EQ(ReadRegisterJson(), R"({
    "namespace": {
        "k": "v"
    }
})");

  ComponentData data2;
  data2.set_namespace_("namespace");
  data2.set_annotations({
      {"k2", "v2"},
  });

  Upsert(std::move(data2));

  EXPECT_THAT(data_register_->Get(), UnorderedElementsAreArray({
                                         Pair("namespace.k", "v"),
                                     }));
  EXPECT_TRUE(data_register_->IsMissingAnnotations());
  EXPECT_EQ(ReadRegisterJson(), R"({
    "namespace": {
        "k": "v"
    }
})");
}

TEST_F(DataRegisterTest, Upsert_NoUpdatesOnEmptyAnnotations) {
  ComponentData data;
  data.set_namespace_("namespace");
  data.set_annotations({
      {"k", "v"},
  });

  Upsert(std::move(data));

  EXPECT_THAT(data_register_->Get(), UnorderedElementsAreArray({
                                         Pair("namespace.k", "v"),
                                     }));
  EXPECT_FALSE(data_register_->IsMissingAnnotations());
  EXPECT_EQ(ReadRegisterJson(), R"({
    "namespace": {
        "k": "v"
    }
})");

  // We upsert another ComponentData with no annotations.
  ComponentData data2;

  Upsert(std::move(data2));

  // We check that the DataRegister's namespaced annotations and AttachmentManager's non-platform
  // annotations are still the same.
  EXPECT_THAT(data_register_->Get(), UnorderedElementsAreArray({
                                         Pair("namespace.k", "v"),
                                     }));
  EXPECT_FALSE(data_register_->IsMissingAnnotations());
  EXPECT_EQ(ReadRegisterJson(), R"({
    "namespace": {
        "k": "v"
    }
})");
}

TEST_F(DataRegisterTest, Upsert_InsertIfDifferentNamespaces) {
  ComponentData data;
  data.set_namespace_("namespace");
  data.set_annotations({
      {"k", "v"},
  });

  Upsert(std::move(data));

  EXPECT_THAT(data_register_->Get(), UnorderedElementsAreArray({
                                         Pair("namespace.k", "v"),
                                     }));
  EXPECT_FALSE(data_register_->IsMissingAnnotations());
  EXPECT_EQ(ReadRegisterJson(), R"({
    "namespace": {
        "k": "v"
    }
})");

  // We upsert another ComponentData with the same annotations, but under a different namespace.
  ComponentData data2;
  data2.set_namespace_("namespace2");
  data2.set_annotations({
      {"k", "v"},
  });

  Upsert(std::move(data2));

  EXPECT_THAT(data_register_->Get(), UnorderedElementsAreArray({
                                         Pair("namespace.k", "v"),
                                         Pair("namespace2.k", "v"),
                                     }));
  EXPECT_FALSE(data_register_->IsMissingAnnotations());
  EXPECT_EQ(ReadRegisterJson(), R"({
    "namespace": {
        "k": "v"
    },
    "namespace2": {
        "k": "v"
    }
})");
}

TEST_F(DataRegisterTest, Upsert_InsertIfDifferentKey) {
  ComponentData data;
  data.set_namespace_("namespace");
  data.set_annotations({
      {"k", "v"},
  });

  Upsert(std::move(data));

  EXPECT_THAT(data_register_->Get(), UnorderedElementsAreArray({
                                         Pair("namespace.k", "v"),
                                     }));
  EXPECT_FALSE(data_register_->IsMissingAnnotations());

  // We upsert another ComponentData under the same namespace, but with a different key.
  ComponentData data2;
  data2.set_namespace_("namespace");
  data2.set_annotations({
      {"k2", "v2"},
  });

  Upsert(std::move(data2));

  EXPECT_THAT(data_register_->Get(), UnorderedElementsAreArray({
                                         Pair("namespace.k", "v"),
                                         Pair("namespace.k2", "v2"),
                                     }));
  EXPECT_FALSE(data_register_->IsMissingAnnotations());
  EXPECT_EQ(ReadRegisterJson(), R"({
    "namespace": {
        "k": "v",
        "k2": "v2"
    }
})");
}

TEST_F(DataRegisterTest, Upsert_UpdateIfSameKey) {
  ComponentData data;
  data.set_namespace_("namespace");
  data.set_annotations({
      {"k", "v"},
  });

  Upsert(std::move(data));

  EXPECT_THAT(data_register_->Get(), UnorderedElementsAreArray({
                                         Pair("namespace.k", "v"),
                                     }));
  EXPECT_FALSE(data_register_->IsMissingAnnotations());
  EXPECT_EQ(ReadRegisterJson(), R"({
    "namespace": {
        "k": "v"
    }
})");

  // We upsert another ComponentData under the same namespace and the same key.
  ComponentData data2;
  data2.set_namespace_("namespace");
  data2.set_annotations({
      {"k", "v2"},
  });

  Upsert(std::move(data2));

  EXPECT_THAT(data_register_->Get(), UnorderedElementsAreArray({
                                         Pair("namespace.k", "v2"),
                                     }));
  EXPECT_FALSE(data_register_->IsMissingAnnotations());
  EXPECT_EQ(ReadRegisterJson(), R"({
    "namespace": {
        "k": "v2"
    }
})");
}

TEST_F(DataRegisterTest, ReinitializesFromJson) {
  ComponentData data1;
  data1.set_namespace_("namespace1");
  data1.set_annotations({
      {"k1", "v1"},
      {"k2", "v2"},
  });

  Upsert(std::move(data1));

  ComponentData data2;
  data2.set_namespace_("namespace2");
  data2.set_annotations({
      {"k3", "v3"},
      {"k4", "v4"},
  });

  Upsert(std::move(data2));

  MakeNewDataRegister();
  EXPECT_THAT(data_register_->Get(), UnorderedElementsAreArray({
                                         Pair("namespace1.k1", "v1"),
                                         Pair("namespace1.k2", "v2"),
                                         Pair("namespace2.k3", "v3"),
                                         Pair("namespace2.k4", "v4"),
                                     }));
  EXPECT_FALSE(data_register_->IsMissingAnnotations());
}

}  // namespace
}  // namespace forensics::feedback
