// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COURGETTE_COURGETTE_FLOW_H_
#define COURGETTE_COURGETTE_FLOW_H_

#include <memory>
#include <string>

#include "base/macros.h"
#include "courgette/courgette.h"
#include "courgette/region.h"
#include "courgette/streams.h"

namespace courgette {

class AssemblyProgram;
class Disassembler;
class EncodedProgram;

// An adaptor for Region as BasicBuffer.
class RegionBuffer : public BasicBuffer {
 public:
  explicit RegionBuffer(const Region& region) : region_(region) {}
  ~RegionBuffer() override {}

  // BasicBuffer:
  const uint8_t* data() const override { return region_.start(); }
  size_t length() const override { return region_.length(); }

 private:
  Region region_;

  DISALLOW_COPY_AND_ASSIGN(RegionBuffer);
};

// CourgetteFlow stores Courgette data arranged into groups, and exposes
// "commands" that operate on them. On the first occurrence of an error, the
// Courgette error code is recorded, error messages are generated and stored,
// and all subsequent commands become no-op. This allows callers to concisely
// specify high-level logic with minimal code for error handling.
class CourgetteFlow {
 public:
  // A group of Courgette data, for a single executable. Takes negligible space
  // when unused.
  struct Data {
    Data();
    ~Data();

    std::unique_ptr<Disassembler> disassembler;
    std::unique_ptr<AssemblyProgram> program;
    std::unique_ptr<EncodedProgram> encoded;
    SinkStreamSet sinks;
    SourceStreamSet sources;
  };

  // Group enumeration into |data_*_| fields.
  enum Group {
    ONLY,  // The only file processed.
    OLD,   // The "old" file during patching.
    NEW,   // The "new" file during patching.
  };

  CourgetteFlow();
  ~CourgetteFlow();

  static const char* name(Group group);
  Data* data(Group group);  // Allows caller to modify.
  bool ok();
  bool failed();
  Status status();
  const std::string& message();

  // Commands that perform no-op on error. This allows caller to concisely
  // specify high-level logic, and perform a single error check at the end. Care
  // must be taken w.r.t. error handling if |data()| is harvested between
  // commands.

  // Reads |buffer| to initialize |data(group)->sources|.
  void ReadSourceStreamSetFromBuffer(Group group, const BasicBuffer& buffer);

  // Reads |buffer| to initialize |data(group)->disassembler|.
  void ReadDisassemblerFromBuffer(Group group, const BasicBuffer& buffer);

  // Reads |opt_sources| if given, or else |data(group)->sources| to initialize
  // |data(group).encoded|.
  void ReadEncodedProgramFromSourceStreamSet(
      Group group,
      SourceStreamSet* opt_sources = nullptr);

  // Uses |data(group)->disassembler| to initialize |data(group)->program|,
  // passing |annotate| as initialization parameter (should be true if
  // AdjustNewAssemblyProgramToMatchOld() gets called later).
  void CreateAssemblyProgramFromDisassembler(Group group, bool annotate);

  // Uses |data(group)->disassembler| and |data(group)->program| to initialize
  // |data(group)->encoded|.
  void CreateEncodedProgramFromDisassemblerAndAssemblyProgram(Group group);

  // Serializese |data(group)->sinks| to |sink|.
  void WriteSinkStreamFromSinkStreamSet(Group group, SinkStream* sink);

  // Serializes |data(group)->encoded| to |opt_sinks| if given, or else to
  // |data(group)->sinks|.
  void WriteSinkStreamSetFromEncodedProgram(Group group,
                                            SinkStreamSet* opt_sinks = nullptr);

  // Converts |data(group)->encoded| to an exectuable and writes the result to
  // |sink|.
  void WriteExecutableFromEncodedProgram(Group group, SinkStream* sink);

  // Adjusts |data(NEW)->program| Labels to match |data(OLD)->program| Labels.
  void AdjustNewAssemblyProgramToMatchOld();

  // Destructor commands to reduce memory usage.

  void DestroyDisassembler(Group group);

  void DestroyAssemblyProgram(Group group);

  void DestroyEncodedProgram(Group group);

 private:
  // Utilities to process return values from Courgette functions, and assign
  // |status_| and |message_|. Usage:
  //   if (!check(some_courgette_function(param1, ...)))
  //     setMessage("format string %s...", value1, ...);

  // Reassigns |status_|, and returns true if |C_OK|.
  bool check(Status new_status);

  // check() alternative for functions that return true on success. On failure
  // assigns |status_| to |failure_mode|.
  bool check(bool success, Status failure_mode);

  void setMessage(const char* format, ...);

  Status status_ = C_OK;
  std::string message_;
  Data data_only_;
  Data data_old_;
  Data data_new_;

  DISALLOW_COPY_AND_ASSIGN(CourgetteFlow);
};

}  // namespace courgette

#endif  // COURGETTE_COURGETTE_FLOW_H_
