// 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 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<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)->program|, passing |annotate| as
  // initialization parameter (true if AdjustNewAssemblyProgramToMatchOld() gets
  // called later).
  void ReadAssemblyProgramFromBuffer(Group group,
                                     const BasicBuffer& buffer,
                                     bool annotate);

  // 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)->program| to initialize |data(group)->encoded|.
  void CreateEncodedProgramFromAssemblyProgram(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 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_
