// Copyright (c) 2011 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_PATCH_GENERATOR_X86_32_H_
#define COURGETTE_PATCH_GENERATOR_X86_32_H_

#include "base/logging.h"
#include "base/macros.h"
#include "courgette/courgette_flow.h"
#include "courgette/ensemble.h"
#include "courgette/patcher_x86_32.h"

namespace courgette {

// PatchGeneratorX86_32 is the universal patch generator for all executables,
// performing transformation and adjustment. The executable type is determined
// by the program detector.
class PatchGeneratorX86_32 : public TransformationPatchGenerator {
 public:
  PatchGeneratorX86_32(Element* old_element,
                       Element* new_element,
                       PatcherX86_32* patcher,
                       ExecutableType kind)
      : TransformationPatchGenerator(old_element, new_element, patcher),
        kind_(kind) {
  }

  virtual ExecutableType Kind() { return kind_; }

  Status WriteInitialParameters(SinkStream* parameter_stream) {
    if (!parameter_stream->WriteSizeVarint32(
            old_element_->offset_in_ensemble()) ||
        !parameter_stream->WriteSizeVarint32(old_element_->region().length())) {
      return C_STREAM_ERROR;
    }
    return C_OK;
    // TODO(sra): Initialize |patcher_| with these parameters.
  }

  Status PredictTransformParameters(SinkStreamSet* prediction) {
    return TransformationPatchGenerator::PredictTransformParameters(prediction);
  }

  Status CorrectedTransformParameters(SinkStreamSet* parameters) {
    // No code needed to write an 'empty' parameter set.
    return C_OK;
  }

  // The format of a transformed_element is a serialized EncodedProgram. Steps:
  // - Form Disassembler for the old and new Elements.
  // - Extract AssemblyPrograms from old and new Disassemblers.
  // - Adjust the new AssemblyProgram to make it as much like the old one as
  //   possible.
  // - Serialize old and new Disassembler to EncodedProgram, using the old
  //   AssemblyProgram and the adjusted new AssemblyProgram.
  // The steps are performed in an order to reduce peak memory.
  Status Transform(SourceStreamSet* corrected_parameters,
                   SinkStreamSet* old_transformed_element,
                   SinkStreamSet* new_transformed_element) {
    // Don't expect any corrected parameters.
    if (!corrected_parameters->Empty())
      return C_GENERAL_ERROR;

    // Flow graph and process sequence (DA = Disassembler, AP = AssemblyProgram,
    // EP = EncodedProgram, Adj = Adjusted):
    //   [1 Old DA] --> [2 Old AP]   [6 New AP] <-- [5 New DA]
    //       |            |   |          |              |
    //       v            |   |          v (move)       v
    //   [3 Old EP] <-----+   +->[7 Adj New AP] --> [8 New EP]
    //   (4 Write)                                  (9 Write)
    CourgetteFlow flow;
    RegionBuffer old_buffer(old_element_->region());
    RegionBuffer new_buffer(new_element_->region());
    flow.ReadDisassemblerFromBuffer(flow.OLD, old_buffer);                  // 1
    flow.CreateAssemblyProgramFromDisassembler(flow.OLD, true);             // 2
    flow.CreateEncodedProgramFromDisassemblerAndAssemblyProgram(flow.OLD);  // 3
    flow.DestroyDisassembler(flow.OLD);
    flow.WriteSinkStreamSetFromEncodedProgram(flow.OLD,
                                              old_transformed_element);  // 4
    flow.DestroyEncodedProgram(flow.OLD);
    flow.ReadDisassemblerFromBuffer(flow.NEW, new_buffer);       // 5
    flow.CreateAssemblyProgramFromDisassembler(flow.NEW, true);  // 6
    flow.AdjustNewAssemblyProgramToMatchOld();                   // 7
    flow.DestroyAssemblyProgram(flow.OLD);
    flow.CreateEncodedProgramFromDisassemblerAndAssemblyProgram(flow.NEW);  // 8
    flow.DestroyAssemblyProgram(flow.NEW);
    flow.DestroyDisassembler(flow.NEW);
    flow.WriteSinkStreamSetFromEncodedProgram(flow.NEW,
                                              new_transformed_element);  // 9
    if (flow.failed()) {
      LOG(ERROR) << flow.message() << " (" << old_element_->Name() << " => "
                 << new_element_->Name() << ")";
    }
    return flow.status();
  }

  Status Reform(SourceStreamSet* transformed_element,
                SinkStream* reformed_element) {
    return TransformationPatchGenerator::Reform(transformed_element,
                                                reformed_element);
  }

 private:
  virtual ~PatchGeneratorX86_32() { }

  ExecutableType kind_;

  DISALLOW_COPY_AND_ASSIGN(PatchGeneratorX86_32);
};

}  // namespace courgette

#endif  // COURGETTE_PATCH_GENERATOR_X86_32_H_
