/*
 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_baselinefile.h"

#include <stdio.h>

#include <algorithm>
#include <memory>
#include <vector>

#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_fileutils.h"
#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h"
#include "webrtc/rtc_base/constructormagic.h"
#include "webrtc/test/testsupport/fileutils.h"

namespace webrtc {
namespace testing {
namespace bwe {

// The format of BWE test baseline files is extremely simple:
//   1. All read/written entities are 32-bit unsigned integers in network byte
//      order (Big Endian).
//   2. Files beging with a 2 word header containing a magic marker and file
//      format version indicator. The Magic marker reads "BWE!" in a hex dump.
//   3. Each estimate is logged as a pair of words: time in milliseconds and
//      estimated bit rate, in bits per second.
const uint32_t kMagicMarker = 0x42574521;
const uint32_t kFileVersion1 = 0x00000001;
const char kResourceSubDir[] = "remote_bitrate_estimator";

class BaseLineFileVerify : public BaseLineFileInterface {
 public:
  // If |allow_missing_file| is set, VerifyOrWrite() will return true even if
  // the baseline file is missing. This is the default when verifying files, but
  // not when updating (i.e. we always write it out if missing).
  BaseLineFileVerify(const std::string& filepath, bool allow_missing_file)
      : reader_(),
        fail_to_read_response_(false) {
    std::unique_ptr<ResourceFileReader> reader;
    reader.reset(ResourceFileReader::Create(filepath, "bin"));
    if (!reader.get()) {
      printf("WARNING: Missing baseline file for BWE test: %s.bin\n",
             filepath.c_str());
      fail_to_read_response_ = allow_missing_file;
    } else {
      uint32_t magic_marker = 0;
      uint32_t file_version = 0;
      if (reader->Read(&magic_marker) && magic_marker == kMagicMarker &&
          reader->Read(&file_version) && file_version == kFileVersion1) {
        reader_.swap(reader);
      } else {
        printf("WARNING: Bad baseline file header for BWE test: %s.bin\n",
               filepath.c_str());
      }
    }
  }
  virtual ~BaseLineFileVerify() {}

  virtual void Estimate(int64_t time_ms, uint32_t estimate_bps) {
    if (reader_.get()) {
      uint32_t read_ms = 0;
      uint32_t read_bps = 0;
      if (reader_->Read(&read_ms) && read_ms == time_ms &&
          reader_->Read(&read_bps) && read_bps == estimate_bps) {
      } else {
        printf("ERROR: Baseline differs starting at: %d ms (%d vs %d)!\n",
            static_cast<uint32_t>(time_ms), estimate_bps, read_bps);
        reader_.reset(NULL);
      }
    }
  }

  virtual bool VerifyOrWrite() {
    if (reader_.get()) {
      if (reader_->IsAtEnd()) {
        return true;
      } else {
        printf("ERROR: Baseline file contains more data!\n");
        return false;
      }
    }
    return fail_to_read_response_;
  }

 private:
  std::unique_ptr<ResourceFileReader> reader_;
  bool fail_to_read_response_;

  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(BaseLineFileVerify);
};

class BaseLineFileUpdate : public BaseLineFileInterface {
 public:
  BaseLineFileUpdate(const std::string& filepath,
                     BaseLineFileInterface* verifier)
      : verifier_(verifier),
        output_content_(),
        filepath_(filepath) {
    output_content_.push_back(kMagicMarker);
    output_content_.push_back(kFileVersion1);
  }
  virtual ~BaseLineFileUpdate() {}

  virtual void Estimate(int64_t time_ms, uint32_t estimate_bps) {
    verifier_->Estimate(time_ms, estimate_bps);
    output_content_.push_back(static_cast<uint32_t>(time_ms));
    output_content_.push_back(estimate_bps);
  }

  virtual bool VerifyOrWrite() {
    if (!verifier_->VerifyOrWrite()) {
      std::string dir_path = webrtc::test::OutputPath() + kResourceSubDir;
      if (!webrtc::test::CreateDir(dir_path)) {
        printf("WARNING: Cannot create output dir: %s\n", dir_path.c_str());
        return false;
      }
      std::unique_ptr<OutputFileWriter> writer;
      writer.reset(OutputFileWriter::Create(filepath_, "bin"));
      if (!writer.get()) {
        printf("WARNING: Cannot create output file: %s.bin\n",
            filepath_.c_str());
        return false;
      }
      printf("NOTE: Writing baseline file for BWE test: %s.bin\n",
             filepath_.c_str());
      for (std::vector<uint32_t>::iterator it = output_content_.begin();
          it != output_content_.end(); ++it) {
        writer->Write(*it);
      }
      return true;
    }
    printf("NOTE: No change, not writing: %s\n", filepath_.c_str());
    return true;
  }

 private:
  std::unique_ptr<BaseLineFileInterface> verifier_;
  std::vector<uint32_t> output_content_;
  std::string filepath_;

  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(BaseLineFileUpdate);
};

BaseLineFileInterface* BaseLineFileInterface::Create(
    const std::string& filename, bool write_output_file) {
  std::string filepath = filename;
  std::replace(filepath.begin(), filepath.end(), '/', '_');
  filepath = std::string(kResourceSubDir) + "/" + filepath;

  std::unique_ptr<BaseLineFileInterface> result;
  result.reset(new BaseLineFileVerify(filepath, !write_output_file));
  if (write_output_file) {
    // Takes ownership of the |verifier| instance.
    result.reset(new BaseLineFileUpdate(filepath, result.release()));
  }
  return result.release();
}
}  // namespace bwe
}  // namespace testing
}  // namespace webrtc
