/*
 * Copyright 2021 Bloomberg Finance LP
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <buildboxcommon_protojsonutils.h>

namespace buildboxcommon {

std::unique_ptr<std::string> ProtoJsonUtils::protoToJsonString(
    const ExecutedActionMetadata &executedActionMetadata,
    const ProtoJsonUtils::JsonPrintOptions &options)
{
    if (executedActionAuxiliaryMetadataIsValid(executedActionMetadata)) {
        return protobufMessageToJsonString(executedActionMetadata, options);
    }

    // Clear the contents of `auxiliary_metadata` before generating JSON:
    ExecutedActionMetadata cleanMetadata(executedActionMetadata);
    cleanMetadata.clear_auxiliary_metadata();
    BUILDBOX_LOG_WARNING(
        "`ExecutedActionMetadata.auxiliary_metadata` is not empty or a single "
        "`Digest` message, ignoring the field.");

    return protobufMessageToJsonString(cleanMetadata, options);
}

std::unique_ptr<std::string> ProtoJsonUtils::protoToJsonString(
    const ActionResult &actionResult,
    const ProtoJsonUtils::JsonPrintOptions &options)
{
    if (executedActionAuxiliaryMetadataIsValid(
            actionResult.execution_metadata())) {
        return protobufMessageToJsonString(actionResult, options);
    }

    // Clear the contents of `auxiliary_metadata` before generating JSON:
    ActionResult cleanActionResult(actionResult);
    cleanActionResult.mutable_execution_metadata()->clear_auxiliary_metadata();
    BUILDBOX_LOG_WARNING("`ActionResult.execution_metadata.auxiliary_metadata`"
                         " is not empty or a single "
                         "`Digest` message, ignoring the field.");
    return protobufMessageToJsonString(cleanActionResult, options);
}

bool ProtoJsonUtils::executedActionAuxiliaryMetadataIsValid(
    const ExecutedActionMetadata &executedActionMetadata)
{
    return executedActionMetadata.auxiliary_metadata().empty() ||
           (executedActionMetadata.auxiliary_metadata_size() == 1 &&
            executedActionMetadata.auxiliary_metadata(0).Is<Digest>());
}

void jsonOptionsAlwaysPrintFieldsWithNoPresence(
    ProtoJsonUtils::JsonPrintOptions &options)
{
#if PROTOBUF_HAS_PRINT_OPTIONS_ALWAYS_PRINT_FIELDS_WITH_NO_PRESENCE
    options.always_print_fields_with_no_presence = true;
#elif PROTOBUF_HAS_PRINT_OPTIONS_ALWAYS_PRINT_WITHOUT_PRESENCE_FIELDS
    options.always_print_without_presence_field = true;
#else
    options.always_print_primitive_fields = true;
#endif
}

} // namespace buildboxcommon
