// Copyright (c) 2019 Dev Null Productions

#include <xrpld/app/main/Application.h>
#include <xrpld/rpc/Context.h>

#include <xrpl/basics/base64.h>
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/jss.h>

namespace xrpl {
Json::Value
doManifest(RPC::JsonContext& context)
{
    auto& params = context.params;

    if (!params.isMember(jss::public_key))
        return RPC::missing_field_error(jss::public_key);

    auto const requested = params[jss::public_key].asString();

    Json::Value ret;
    ret[jss::requested] = requested;

    auto const pk = parseBase58<PublicKey>(TokenType::NodePublic, requested);
    if (!pk)
    {
        RPC::inject_error(rpcINVALID_PARAMS, ret);
        return ret;
    }

    // first attempt to use params as ephemeral key,
    // if this lookup succeeds master key will be returned,
    // else an unseated optional is returned
    auto const mk = context.app.validatorManifests().getMasterKey(*pk);

    auto const ek = context.app.validatorManifests().getSigningKey(mk);

    // if ephemeral key not found, we don't have specified manifest
    if (!ek)
        return ret;

    if (auto const manifest = context.app.validatorManifests().getManifest(mk))
        ret[jss::manifest] = base64_encode(*manifest);
    Json::Value details;

    details[jss::master_key] = toBase58(TokenType::NodePublic, mk);
    details[jss::ephemeral_key] = toBase58(TokenType::NodePublic, *ek);

    if (auto const seq = context.app.validatorManifests().getSequence(mk))
        details[jss::seq] = *seq;

    if (auto const domain = context.app.validatorManifests().getDomain(mk))
        details[jss::domain] = *domain;

    ret[jss::details] = details;
    return ret;
}
}  // namespace xrpl
