//===-- Action.h ----------------------------------------------------------===//
//
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
//===----------------------------------------------------------------------===//
//
// Defines the Action class (helper for driver functionality).
//
//===----------------------------------------------------------------------===//

#ifndef GOLLVM_DRIVER_ACTION_H
#define GOLLVM_DRIVER_ACTION_H

#include "llvm/ADT/SmallVector.h"

namespace gollvm {
namespace driver {

class Action;
class Artifact;
class InputAction;
class ReadStdinAction;

// Action lists contain pointers to actions owned by a Compilation.
typedef llvm::SmallVector<Action*, 3> ActionList;

// An abstract compilation action, such as "assemble this asm src
// file" or "link this set of objects together into a new file".
// Actions are assumed to have a single output. There is also a
// pseudo-action InputAction that that corresponds to the action of
// reading an file. An action consumes inputs from a set of other
// actions.

class Action {
 public:

  // Type of action
  enum Type {
    A_InputFile,
    A_ReadStdin,
    A_CompileAndAssemble,
    A_Compile,
    A_Assemble,
    A_Link
  };

  explicit Action(Type t) : type_(t) { }
  Action(Type t, Action *input) : type_(t), inputs_(ActionList({input})){ }
  Action(Type t, ActionList &il) : type_(t), inputs_(il) { }
  virtual ~Action() = default;

  const ActionList &inputs() const { return inputs_; }

  Type type() const { return type_; }

  inline InputAction *castToInputAction();
  inline const InputAction *castToInputAction() const;
  inline ReadStdinAction *castToReadStdinAction();
  inline const ReadStdinAction *castToReadStdinAction() const;

  const char *getName() const;
  const char *resultFileSuffix() const;

  // debugging
  void dump();

  // unit testing
  std::string toString();

 private:
  Type type_;
  ActionList inputs_;
};

// An input action corresponds to the reading of some input artifact.

class InputAction : public Action {
 public:
  explicit InputAction(Artifact *input)
      : Action(Action::A_InputFile),
        input_(input) { }
  Artifact *input() const { return input_; }
 private:
  Artifact *input_;
};

// An input action that corresponds to the reading stdin.

class ReadStdinAction : public Action {
 public:
  explicit ReadStdinAction(const char *suffix)
      : Action(Action::A_ReadStdin),
        suffix_(suffix) { }
  const char *suffix() const { return suffix_; }
 private:
  const char *suffix_;
};

inline InputAction *Action::castToInputAction()
{
  return type_ == A_InputFile ? static_cast<InputAction*>(this) : nullptr;
}

inline const InputAction *Action::castToInputAction() const
{
  return type_ == A_InputFile ? static_cast<const InputAction*>(this) : nullptr;
}

inline ReadStdinAction *Action::castToReadStdinAction()
{
  return type_ == A_ReadStdin ? static_cast<ReadStdinAction*>(this) : nullptr;
}

inline const ReadStdinAction *Action::castToReadStdinAction() const
{
  return type_ == A_ReadStdin ? static_cast<const ReadStdinAction*>(this) : nullptr;
}

} // end namespace driver
} // end namespace gollvm

#endif // GOLLVM_DRIVER_ACTION_H
