// Copyright 2015 Google Inc. All rights reserved
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef VAR_H_
#define VAR_H_

#include <memory>
#include <string>
#include <unordered_map>
#include <unordered_set>

#include "eval.h"
#include "expr.h"
#include "log.h"
#include "stmt.h"
#include "string_piece.h"
#include "symtab.h"

using namespace std;

class Evaluator;
class Value;

enum struct VarOrigin : char {
  UNDEFINED,
  DEFAULT,
  ENVIRONMENT,
  ENVIRONMENT_OVERRIDE,
  FILE,
  COMMAND_LINE,
  OVERRIDE,
  AUTOMATIC,
};

const char* GetOriginStr(VarOrigin origin);

class Var : public Evaluable {
 public:
  virtual ~Var();

  virtual const char* Flavor() const = 0;

  VarOrigin Origin() { return origin_; }
  virtual bool IsDefined() const { return true; }

  virtual void AppendVar(Evaluator* ev, Value* v);

  virtual StringPiece String() const = 0;

  virtual string DebugString() const = 0;

  bool ReadOnly() const { return readonly_; }
  void SetReadOnly() { readonly_ = true; }

  bool Deprecated() const { return deprecated_; }
  void SetDeprecated(const StringPiece& msg);

  bool Obsolete() const { return obsolete_; }
  void SetObsolete(const StringPiece& msg);

  const string& DeprecatedMessage() const;

  // This variable was used (either written or read from)
  void Used(Evaluator* ev, const Symbol& sym) const;

  AssignOp op() const { return assign_op_; }
  void SetAssignOp(AssignOp op) { assign_op_ = op; }

  static Var* Undefined();

 protected:
  Var();
  explicit Var(VarOrigin origin);

 private:
  const VarOrigin origin_;
  AssignOp assign_op_;
  bool readonly_ : 1;
  bool deprecated_ : 1;
  bool obsolete_ : 1;

  const char* diagnostic_message_text() const;

  static unordered_map<const Var*, string> diagnostic_messages_;
};

class SimpleVar : public Var {
 public:
  explicit SimpleVar(VarOrigin origin);
  SimpleVar(const string& v, VarOrigin origin);
  SimpleVar(VarOrigin, Evaluator* ev, Value* v);

  virtual const char* Flavor() const override { return "simple"; }

  virtual void Eval(Evaluator* ev, string* s) const override;

  virtual void AppendVar(Evaluator* ev, Value* v) override;

  virtual StringPiece String() const override;

  virtual string DebugString() const override;

 private:
  string v_;
};

class RecursiveVar : public Var {
 public:
  RecursiveVar(Value* v, VarOrigin origin, StringPiece orig);

  virtual const char* Flavor() const override { return "recursive"; }

  virtual void Eval(Evaluator* ev, string* s) const override;

  virtual void AppendVar(Evaluator* ev, Value* v) override;

  virtual StringPiece String() const override;

  virtual string DebugString() const override;

 private:
  Value* v_;
  StringPiece orig_;
};

class UndefinedVar : public Var {
 public:
  UndefinedVar();

  virtual const char* Flavor() const override { return "undefined"; }
  virtual bool IsDefined() const override { return false; }

  virtual void Eval(Evaluator* ev, string* s) const override;

  virtual StringPiece String() const override;

  virtual string DebugString() const override;
};

class Vars : public unordered_map<Symbol, Var*> {
 public:
  ~Vars();

  Var* Lookup(Symbol name) const;
  Var* Peek(Symbol name) const;

  void Assign(Symbol name, Var* v, bool* readonly);

  static void add_used_env_vars(Symbol v);

  static const SymbolSet used_env_vars() { return used_env_vars_; }

 private:
  static SymbolSet used_env_vars_;
};

class ScopedVar {
 public:
  // Does not take ownerships of arguments.
  ScopedVar(Vars* vars, Symbol name, Var* var);
  ~ScopedVar();

 private:
  Vars* vars_;
  Var* orig_;
  Vars::iterator iter_;
};

#endif  // VAR_H_
