#include "bmcweb_authorizer_singleton.h"

#include <array>
#include <cstddef>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <iterator>
#include <map>
#include <string>
#include <string_view>
#include <unordered_set>
#include <utility>
#include <vector>

#include "gmi/machine_identity.pb.h"
#include "tlbmc/feed_client_interface.h"
#include "one/network_interfaces.pb.h"
#include "one/offline_node_entities.pb.h"
#include "one/resolved_entities.pb.h"
#include "one/public_offline_node_entities.h"
#include "absl/base/no_destructor.h"
#include "absl/container/flat_hash_set.h"
#include "absl/log/log.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"
#include "absl/strings/substitute.h"
#include "boost/beast/http/verb.hpp"  // NOLINT
#include "authorizer_enums.h"
#include "redfish_v1.pb.h"
#include "grpc/grpc_security_constants.h"
#include "grpcpp/security/auth_context.h"
#include "grpcpp/support/status.h"
#include "grpcpp/support/string_ref.h"
#include "nlohmann/json.hpp"
#include "config_parser.h"
#include "oauth_utils.h"
#include "redfish_authorizer.h"
#include "redfish_privileges.h"
#include "zatar/certificate_metadata.h"

namespace milotic::authz {

namespace {

using ::ecclesia::Operation;
using ::ecclesia::ResourceEntity;
using ::milotic::redfish::CertificateMetadata;
using ::milotic::redfish::CertificateMetadataParser;
using ::production_msv::node_entities::ReadOfflineNodeEntityInformation;
using ::production_msv::node_entities_proto::NetworkInterface;
using ::production_msv::node_entities_proto::OfflineNodeEntityInformation;
using ::production_msv::node_entities_proto::ResolvedNodeEntity;
using ::security_prodid::GoogleMachineIdentityProto;

}  // namespace

BmcWebAuthorizerSingleton& BmcWebAuthorizerSingleton::Initialize(
    const AuthorizerOptions& options, std::string_view oauth_key_path) {
  static absl::NoDestructor<BmcWebAuthorizerSingleton> singleton(
      options, oauth_key_path);

  return *singleton;
}

void BmcWebAuthorizerSingleton::ReloadRedfishAuthorizer(
    const std::string& configuration_path) {
  redfish_authorizer_.ReloadConfiguration(configuration_path);
}

void BmcWebAuthorizerSingleton::RegisterAnycastUser(
    const std::string& service,
    platforms_syshealth::collection::feed::AnycastUser* user) {
  redfish_authorizer_.RegisterAnycastUser(service, user);
}

BmcWebAuthorizerSingleton& BmcWebAuthorizerSingleton::GetInstance() {
  return Initialize(/*options=*/{}, /*oauth_key_path=*/"");
}

BmcWebAuthorizerSingleton::BmcWebAuthorizerSingleton(
    const AuthorizerOptions& options, std::string_view oauth_key_path)
    : tlbmc_trust_bundle_install_module_is_enabled_(
          options.tlbmc_trust_bundle_install_module_is_enabled),
      gmi_path_(options.google_machine_identity_path),
      oauth_key_path_(oauth_key_path),
      offline_node_entity_path_(options.offline_node_entities_path),
      redfish_authorizer_(options) {
  ReloadConfiguration();
}

void BmcWebAuthorizerSingleton::ReloadGmiPaths(std::string_view gmi_path) {
  gmi_path_ = gmi_path;
}

void BmcWebAuthorizerSingleton::ReloadConfiguration() {
  LOG(WARNING) << "Reload configuration started..";
  redfish_authorizer_.ReloadConfiguration();
  std::string primary_fqdn = ReadPrimaryFqdnFromGmi();
  SetPrimaryFqdn(primary_fqdn);
  SetOauthKey(ReadOauthKeyFromFile());
  SetInterfaceFqdns(ReadDomainNameFromOfflineNodeEntity(primary_fqdn));
  LOG(WARNING) << "Reload configuration done.";
}

grpc::Status BmcWebAuthorizerSingleton::RecordNewSubscription(
    const PeerSpiffeIdentity& peer) {
  if (absl::Status status = redfish_authorizer_.RecordNewSubscription(peer);
      !status.ok()) {
    return grpc::Status(grpc::StatusCode::PERMISSION_DENIED, status.ToString());
  }
  return grpc::Status::OK;
}

grpc::Status BmcWebAuthorizerSingleton::RecordNewUnsubscription(
    const PeerSpiffeIdentity& peer) {
  if (absl::Status status = redfish_authorizer_.RecordNewUnsubscription(peer);
      !status.ok()) {
    return grpc::Status(grpc::StatusCode::PERMISSION_DENIED, status.ToString());
  }
  return grpc::Status::OK;
}

grpc::Status BmcWebAuthorizerSingleton::Authorize(
    std::string_view uri, boost::beast::http::verb verb,
    const RequestState& request_state) const {
  if (!request_state.peer_authenticated) {
    if (request_state.with_trust_bundle) {
      return grpc::Status(
          grpc::StatusCode::UNAUTHENTICATED,
          "Peer must be authenticated if BMC has trust bundle!");
    }
    if (tlbmc_trust_bundle_install_module_is_enabled_) {
      return RecoveryAuthorizeForBloom(uri, verb);
    }

    return AuthorizeWithoutTrustBundle(uri, verb);
  }

  return AuthorizeWithTrustBundle(uri, verb, request_state);
}

grpc::Status BmcWebAuthorizerSingleton::AuthorizeWithTrustBundle(
    std::string_view uri, boost::beast::http::verb verb,
    const RequestState& request_state) const {
  Operation operation = BoostVerbToOperation(verb);
  RedfishPrivileges peer_privileges =
      RedfishPrivileges(request_state.peer_privileges);
  if (!redfish_authorizer_.IsPeerAuthorized(uri, operation, peer_privileges)) {
    return grpc::Status(grpc::StatusCode::PERMISSION_DENIED,
                        "Client doesn't have enough permissions: " +
                            peer_privileges.GetDebugString());
  }
  return grpc::Status::OK;
}

Operation BmcWebAuthorizerSingleton::BoostVerbToOperation(
    boost::beast::http::verb verb) {
  switch (verb) {
    case boost::beast::http::verb::get:
      return Operation::kGet;
    case boost::beast::http::verb::post:
      return Operation::kPost;
    case boost::beast::http::verb::delete_:
      return Operation::kDelete;
    case boost::beast::http::verb::put:
      return Operation::kPut;
    case boost::beast::http::verb::patch:
      return Operation::kPatch;
    case boost::beast::http::verb::head:
      return Operation::kHead;
    default:
      return Operation::kUndefined;
  }
}

grpc::Status BmcWebAuthorizerSingleton::AuthorizeWithoutTrustBundle(
    std::string_view uri, boost::beast::http::verb verb) const {
  constexpr std::array<std::pair<ResourceEntity, boost::beast::http::verb>, 10>
      kRecoveryOperations = {
          std::pair<ResourceEntity, boost::beast::http::verb>{
              ResourceEntity::kServiceRoot, boost::beast::http::verb::get},
          {ResourceEntity::kChassisCollection, boost::beast::http::verb::get},
          {ResourceEntity::kChassis, boost::beast::http::verb::get},
          {ResourceEntity::kActionInfo, boost::beast::http::verb::get},
          {ResourceEntity::kChassis, boost::beast::http::verb::post},
          {ResourceEntity::kComputerSystem, boost::beast::http::verb::get},
          {ResourceEntity::kComputerSystemCollection,
           boost::beast::http::verb::get},
          {ResourceEntity::kComputerSystem, boost::beast::http::verb::post},
          {ResourceEntity::kManagerCollection, boost::beast::http::verb::get},
          {ResourceEntity::kManager, boost::beast::http::verb::get},
      };
  ResourceEntity entity = GetEntityTypeFromRedfishUri(uri);
  bool authorized = false;
  for (auto const& [allowed_entity, allowed_verb] : kRecoveryOperations) {
    if (entity == allowed_entity && verb == allowed_verb) {
      authorized = true;
      break;
    }
  }

  // Specifically hardcode the Manager.Reset operation to be allowed.
  if (uri == "/redfish/v1/Managers/bmc/Actions/Manager.Reset" &&
      verb == boost::beast::http::verb::post) {
    authorized = true;
  }

  if (!authorized) {
    return grpc::Status(
        grpc::StatusCode::PERMISSION_DENIED,
        "Without trust bundle, only recovery operations are allowed");
  }

  return grpc::Status::OK;
}

grpc::Status BmcWebAuthorizerSingleton::RecoveryAuthorizeForBloom(
    std::string_view uri, boost::beast::http::verb verb) const {
  // allowlist during trust bundle installation
  static const absl::NoDestructor<absl::flat_hash_set<
      std::pair<std::string_view, boost::beast::http::verb>>>
      kAllowedEndpoints({
          {"/redfish/v1/CertificateService", boost::beast::http::verb::get},
          {"/redfish/v1/CertificateService/ReplaceCertificateActionInfo",
           boost::beast::http::verb::get},
          {"/redfish/v1/CertificateService/Actions/"
           "CertificateService.ReplaceCertificate",
           boost::beast::http::verb::post},
      });

  if (kAllowedEndpoints->contains({uri, verb})) {
    return grpc::Status::OK;
  }

  return grpc::Status(
      grpc::StatusCode::PERMISSION_DENIED,
      "Please install your client *CA* certificate as trust bundle first.");
}

grpc::Status BmcWebAuthorizerSingleton::GetPeerRoleFromAuthContext(
    const grpc::AuthContext& context, std::string& peer_role) const {
  PeerSpiffeIdentity peer_identity;
  if (grpc::Status status =
          GetPeerIdentityFromAuthContext(context, peer_identity);
      !status.ok()) {
    peer_role.clear();
    return status;
  }
  peer_role = redfish_authorizer_.GetPeerRedfishRole(peer_identity);
  if (peer_role.empty()) {
    return grpc::Status(
        grpc::StatusCode::PERMISSION_DENIED,
        absl::StrCat(
            "Peer role is not specified in the auth config: peer_identity=",
            peer_identity.spiffe_id));
  }
  return grpc::Status::OK;
}

grpc::Status BmcWebAuthorizerSingleton::GetPrivilegesViaOAuth(
    const grpc::AuthContext& context, const std::string& token,
    std::unordered_set<std::string>& peer_privileges) const {
  PeerSpiffeIdentity peer_identity;
  if (grpc::Status status =
          GetPeerIdentityFromAuthContext(context, peer_identity);
      !status.ok()) {
    return status;
  }

  std::string redfish_role;
  constexpr const char* kExpectedIssuer = "BMC Local Authorization Server";
  if (grpc::Status status = VerifyAndExtractRoleFromToken(
          token, GetOauthKey(), GenerateOAuthSubject(peer_identity),
          GetPrimaryFqdn(), kExpectedIssuer, redfish_role);
      !status.ok()) {
    return status;
  }

  peer_privileges = redfish_authorizer_.GetRedfishPrivileges(redfish_role);
  return grpc::Status::OK;
}

grpc::Status BmcWebAuthorizerSingleton::GetPrivilegesViaMTls(
    const grpc::AuthContext& context,
    std::unordered_set<std::string>& peer_privileges) const {
  PeerSpiffeIdentity peer_identity;
  if (grpc::Status status =
          GetPeerIdentityFromAuthContext(context, peer_identity);
      !status.ok()) {
    return status;
  }
  LOG(INFO) << "Peer identity: " << peer_identity.spiffe_id;
  peer_privileges = redfish_authorizer_.GetPeerRedfishPrivileges(peer_identity);
  return grpc::Status::OK;
}

std::string BmcWebAuthorizerSingleton::ReadPrimaryFqdnFromGmi() const {
  std::ifstream gmi_file(gmi_path_);
  if (!gmi_file.is_open()) {
    LOG(WARNING) << "GMI file at '" << gmi_path_ << "' is missing." << '\n';
    return "";
  }
  GoogleMachineIdentityProto gmi;
  if (!gmi.ParseFromIstream(&gmi_file)) {
    std::cerr << "GMI parsing failed at '" << gmi_path_ << "'" << '\n';
    return "";
  }
  return gmi.fqdn();
}

std::string BmcWebAuthorizerSingleton::ReadOauthKeyFromFile() const {
  std::ifstream oauth_key_file(oauth_key_path_);
  if (!oauth_key_file.is_open()) {
    LOG(WARNING) << "OAuth key file at '" << oauth_key_path_ << "' is missing."
                 << '\n';
    return "";
  }
  std::string oauth_key = {std::istreambuf_iterator<char>(oauth_key_file),
                           std::istreambuf_iterator<char>()};
  return oauth_key;
}

std::vector<std::string>
BmcWebAuthorizerSingleton::ReadDomainNameFromOfflineNodeEntity(
    std::string_view primary_fqdn) const {
  std::ifstream offline_node_entity_file(offline_node_entity_path_);
  std::vector<std::string> interface_fqdns;
  if (!offline_node_entity_file.is_open()) {
    LOG(WARNING) << "Offline Node Entity file at '" << offline_node_entity_path_
                 << "' is missing." << '\n';
    return interface_fqdns;
  }
  absl::StatusOr<OfflineNodeEntityInformation> one =
      ReadOfflineNodeEntityInformation(offline_node_entity_path_);
  if (!one.ok()) {
    LOG(WARNING) << "Could not read offline node entities information: "
                 << one.status().message();
    return interface_fqdns;
  }
  for (const std::pair<const std::string, ResolvedNodeEntity>& entity :
       (*one).resolved_config().entities()) {
    if (absl::StrCat(entity.second.hostname(), ".prod.google.com") !=
        primary_fqdn)
      continue;
    for (const NetworkInterface& intf :
         entity.second.network_interfaces().network_interface()) {
      interface_fqdns.push_back(intf.hostname() + ".prod.google.com");
    }
    break;
  }
  return interface_fqdns;
}

uint64_t BmcWebAuthorizerSingleton::GetSampleRateLimit(
    const std::string& peer_role) const {
  return redfish_authorizer_.GetSampleRateLimit(peer_role);
}

std::string BmcWebAuthorizerSingleton::GetAnycastAddress(
    const std::string& peer_role) const {
  return redfish_authorizer_.GetAnycastAddress(peer_role);
}

ResourceEntity BmcWebAuthorizerSingleton::GetEntityTypeFromRedfishUri(
    std::string_view uri) const {
  return redfish_authorizer_.GetEntityTypeFromRedfishUri(uri);
}

std::size_t BmcWebAuthorizerSingleton::GetNodeIndexInPatternArray(
    std::string_view uri) const {
  return redfish_authorizer_.GetNodeIndexInPatternArray(uri);
}

nlohmann::json BmcWebAuthorizerSingleton::GetRedfishPrivilegeRegistry() const {
  return redfish_authorizer_.GetRedfishPrivilegeRegistry();
}

bool BmcWebAuthorizerSingleton::IsBasePrivilegeRegistryFound() const {
  nlohmann::json config_json = redfish_authorizer_.ParseAuthConfig();

  if (config_json.empty()) {
    return false;
  }

  std::string base_privilege_registry_path =
      redfish_authorizer_.FindBasePrivilegeRegistryPath(config_json);

  return !base_privilege_registry_path.empty();
}

void BmcWebAuthorizerSingleton::SetBasePrivilegesFolder(
    std::string_view base_privileges_folder) {
  redfish_authorizer_.SetBasePrivilegesFolder(base_privileges_folder);
}

grpc::Status BmcWebAuthorizerSingleton::GetPeerIdentityFromAuthContext(
    const grpc::AuthContext& context, PeerSpiffeIdentity& peer_identity) {
  if (!context.IsPeerAuthenticated()) {
    return grpc::Status(grpc::StatusCode::UNAUTHENTICATED,
                        "Peer is unauthenticated");
  }
  if (context.GetPeerIdentityPropertyName() != GRPC_X509_SAN_PROPERTY_NAME) {
    return grpc::Status(grpc::StatusCode::PERMISSION_DENIED,
                        "Peer identity isn't X.509 SAN");
  }
  for (const grpc::string_ref& val : context.GetPeerIdentity()) {
    std::string_view str(val.data(), val.size());
    // As per SPIFFE specification, SPIFFE schema and trust domain are case
    // insensitive.
    // https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE-ID.md#24-spiffe-id-parsing
    if (absl::StartsWithIgnoreCase(str, "spiffe://")) {
      peer_identity.spiffe_id = str;
    } else if (absl::EndsWith(str, ".prod.google.com")) {
      peer_identity.fqdn = str;
    }
  }
  return grpc::Status::OK;
}

grpc::Status BmcWebAuthorizerSingleton::CheckTarget(
    const grpc::AuthContext& grpc_context,
    const std::multimap<grpc::string_ref, grpc::string_ref>& client_metadata,
    const ::redfish::v1::Request& request) const {
  PeerSpiffeIdentity peer_identity;
  if (grpc::Status status =
          GetPeerIdentityFromAuthContext(grpc_context, peer_identity);
      !status.ok()) {
    return status;
  }

  CertificateMetadata peer_metadata;
  if (absl::Status status = metadata_parser_.GetContextAndRoleFromSpiffe(
          peer_identity.spiffe_id, peer_metadata.context, peer_metadata.role);
      !status.ok()) {
    return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, status.ToString());
  }

  // If the service (BMCWeb) has a legitimate GMI, and peer is not a node (e.g.,
  // it's a Borg job), check that the intended recipient of the request matches
  // the identity in the certificate. This is to prevent redirect attacks in
  // powercycle trust model, where clients never verify server.
  std::string primary_fqdn = GetPrimaryFqdn();
  if (primary_fqdn.empty()) {
    LOG(WARNING) << "Can't parse primary fqdn. GMI is probably broken.";
    return grpc::Status::OK;
  }
  if (peer_metadata.context == CertificateMetadataParser::kCaContextNode) {
    return grpc::Status::OK;
  }

  std::string host;
  for (auto const& [key, val] : request.headers()) {
    // Both field name of the Authorization header and the token type are case
    // insensitive
    // References
    // https://www.rfc-editor.org/rfc/rfc7230#section-3.2
    // https://www.rfc-editor.org/rfc/rfc6749#section-5.1
    if (absl::EqualsIgnoreCase(key, "Host")) {
      host = val;
    }
  }

  // To keep backward compatibility, extract host from metadata as well if it's
  // not in headers.
  if (host.empty()) {
    auto it = client_metadata.find("target");
    if (it != client_metadata.end()) {
      host = {it->second.data(), it->second.length()};
    }
  }

  // DNS should be case insensitive
  // Reference: https://www.rfc-editor.org/rfc/rfc4343
  if (absl::EqualsIgnoreCase(host, primary_fqdn)) {
    return grpc::Status::OK;
  }

  // We could have multiple FQDNs on BMC and they can be different from the
  // hostname. Matching any of them should pass the validation
  for (const std::string& fqdn : GetInterfaceFqdns()) {
    if (absl::EqualsIgnoreCase(host, fqdn)) {
      return grpc::Status::OK;
    }
  }

  return grpc::Status(
      grpc::StatusCode::PERMISSION_DENIED,
      absl::Substitute(
          "Unauthorized user: request target doesn't match server; request's "
          "host header='$0'; BMC's primary FQDN='$1'; BMC's interface "
          "FQDNs='$2'",
          host, primary_fqdn, absl::StrJoin(GetInterfaceFqdns(), " ")));
}

void BmcWebAuthorizerSingleton::DeregisterAnycastUser(
    const std::string& service) {
  redfish_authorizer_.DeregisterAnycastUser(service);
}

}  // namespace milotic::authz
