// Copyright 2018 Google Inc.
//
// 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 <fstream>
#include <iostream>
#include <sstream>

#include "absl/strings/escaping.h"
#include "absl/strings/numbers.h"
#include "tink/keyset_handle.h"
#include "tink/prf/prf_set.h"
#include "tink/util/status.h"
#include "testing/cc/cli_util.h"

using crypto::tink::KeysetHandle;
using crypto::tink::PrfSet;

// A command-line utility for testing PrfSet-primitives.
// It requires 4 arguments:
//   keyset-file:  name of the file with the keyset to be used for PrfSet
//   data-file:  name of the file with data for PrfSet input
//   result-file: name of the file for PrfSet output.
//   output-length: length of the prf output in bytes.
//   Format of the output set: <prf_id>:hexencode(<prf_output>)
//   where <prf_id> is the uint32 decimal representation of the ID of the PRF.
//   If the requested output is too long the result should be instead
//   <prf_id>:--.
//   The file is sorted by <prf_id> in the shell script.
int main(int argc, char** argv) {
  if (argc != 5) {
    std::clog << "Usage: " << argv[0]
              << " keyset-file data-file prf-file output-length" << std::endl;
    exit(1);
  }
  std::string keyset_filename(argv[1]);
  std::string data_filename(argv[2]);
  std::string prf_filename(argv[3]);
  size_t output_length;
  if (!absl::SimpleAtoi(argv[4], &output_length)) {
    std::clog << "Output length \"" << argv[4]
              << "\"could not be parsed as integer." << std::endl;
    exit(1);
  }
  std::clog << "Using keyset from file " << keyset_filename
            << " to compute PRF of data from file " << data_filename
            << std::endl
            << "The resulting PRF output will be " << output_length
            << " bytes long and written to the file " << prf_filename
            << std::endl;

  // Init Tink;
  CliUtil::InitTink();

  // Read the keyset.
  std::unique_ptr<KeysetHandle> keyset_handle =
      CliUtil::ReadKeyset(keyset_filename);

  // Get the primitive.
  auto primitive_result = keyset_handle->GetPrimitive<PrfSet>();
  if (!primitive_result.ok()) {
    std::clog << "Getting PRF set-primitive from the keyset failed: "
              << primitive_result.status().error_message() << std::endl;
    exit(1);
  }
  std::unique_ptr<PrfSet> prf_set = std::move(primitive_result.ValueOrDie());

  // Read the data.
  std::string data = CliUtil::Read(data_filename);

  // Compute and write the output.
  std::stringstream result_stream;
  for (const auto& prf_result : prf_set->GetPrfs()) {
    std::clog << "computing PRF for id " << prf_result.first << "..."
              << std::endl;
    result_stream << prf_result.first << ":";
    auto prf_value_result = prf_result.second->Compute(data, output_length);
    if (!prf_value_result.ok()) {
      result_stream << "--" << std::endl;
    } else {
      result_stream << absl::BytesToHexString(prf_value_result.ValueOrDie())
                    << std::endl;
    }
  }
  CliUtil::Write(result_stream.str(), prf_filename);
  std::clog << "All done." << std::endl;
  return 0;
}
