// 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 SYMTAB_H_
#define SYMTAB_H_

#include <bitset>
#include <string>
#include <vector>

#include "string_piece.h"

using namespace std;

extern vector<string*>* g_symbols;

class Symtab;
class Var;

class Symbol {
 public:
  explicit Symbol() : v_(-1) {}

  const string& str() const { return *((*g_symbols)[v_]); }

  const char* c_str() const { return str().c_str(); }

  bool empty() const { return !v_; }

  int val() const { return v_; }

  char get(size_t i) const {
    const string& s = str();
    if (i >= s.size())
      return 0;
    return s[i];
  }

  bool IsValid() const { return v_ >= 0; }

  Var* PeekGlobalVar() const;
  Var* GetGlobalVar() const;
  void SetGlobalVar(Var* v,
                    bool is_override = false,
                    bool* readonly = nullptr) const;

 private:
  explicit Symbol(int v);

  int v_;

  friend class Symtab;
  friend class SymbolSet;
};

/* A set of symbols represented as bitmap indexed by Symbol's ordinal value. */
class SymbolSet {
 public:
  SymbolSet() : low_(0), high_(0) {}

  /* Returns true if Symbol belongs to this set. */
  bool exists(Symbol sym) const {
    size_t bit_nr = static_cast<size_t>(sym.val());
    return sym.IsValid() && bit_nr >= low_ && bit_nr < high_ &&
           bits_[(bit_nr - low_) / 64][(bit_nr - low_) % 64];
  }

  /* Adds Symbol to this set.  */
  void insert(Symbol sym) {
    if (!sym.IsValid()) {
      return;
    }
    size_t bit_nr = static_cast<size_t>(sym.val());
    if (bit_nr < low_ || bit_nr >= high_) {
      resize(bit_nr);
    }
    bits_[(bit_nr - low_) / 64][(bit_nr - low_) % 64] = true;
  }

  /* Returns the number of Symbol's in this set.  */
  size_t size() const {
    size_t n = 0;
    for (auto const& bitset : bits_) {
      n += bitset.count();
    }
    return n;
  }

  /* Allow using foreach.
   * E.g.,
   *   SymbolSet symbol_set;
   *   for (auto const& symbol: symbol_set) { ... }
   */
  class iterator {
    const SymbolSet* bitset_;
    size_t pos_;

    iterator(const SymbolSet* bitset, size_t pos)
        : bitset_(bitset), pos_(pos) {}

    /* Proceed to the next Symbol.  */
    void next() {
      size_t bit_nr = (pos_ > bitset_->low_) ? pos_ - bitset_->low_ : 0;
      while (bit_nr < (bitset_->high_ - bitset_->low_)) {
        if ((bit_nr % 64) == 0 && !bitset_->bits_[bit_nr / 64].any()) {
          bit_nr += 64;
          continue;
        }
        if (bitset_->bits_[bit_nr / 64][bit_nr % 64]) {
          break;
        }
        ++bit_nr;
      }
      pos_ = bitset_->low_ + bit_nr;
    }

   public:
    iterator& operator++() {
      if (pos_ < bitset_->high_) {
        ++pos_;
        next();
      }
      return *this;
    }

    bool operator==(iterator other) const {
      return bitset_ == other.bitset_ && pos_ == other.pos_;
    }

    bool operator!=(iterator other) const { return !(*this == other); }

    Symbol operator*() { return Symbol(pos_); }

    friend class SymbolSet;
  };

  iterator begin() const {
    iterator it(this, low_);
    it.next();
    return it;
  }

  iterator end() const { return iterator(this, high_); }

 private:
  friend class iterator;

  /* Ensure that given bit number is in [low_, high_)  */
  void resize(size_t bit_nr) {
    size_t new_low = bit_nr & ~63;
    size_t new_high = (bit_nr + 64) & ~63;
    if (bits_.empty()) {
      high_ = low_ = new_low;
    }
    if (new_low > low_) {
      new_low = low_;
    }
    if (new_high <= high_) {
      new_high = high_;
    }
    if (new_low == low_) {
      bits_.resize((new_high - new_low) / 64);
    } else {
      std::vector<std::bitset<64> > newbits((new_high - new_low) / 64);
      std::copy(bits_.begin(), bits_.end(),
                newbits.begin() + (low_ - new_low) / 64);
      bits_.swap(newbits);
    }
    low_ = new_low;
    high_ = new_high;
  }

  /* Keep only the (aligned) range where at least one bit has been set.
   * E.g., if we only ever set bits 65 and 141, |low_| will be 64, |high_|
   * will be 192, and |bits_| will have 2 elements.
   */
  size_t low_;
  size_t high_;
  std::vector<std::bitset<64> > bits_;
};

class ScopedGlobalVar {
 public:
  ScopedGlobalVar(Symbol name, Var* var);
  ~ScopedGlobalVar();

 private:
  Symbol name_;
  Var* orig_;
};

inline bool operator==(const Symbol& x, const Symbol& y) {
  return x.val() == y.val();
}

inline bool operator<(const Symbol& x, const Symbol& y) {
  return x.val() < y.val();
}

namespace std {
template <>
struct hash<Symbol> {
  size_t operator()(const Symbol& s) const { return s.val(); }
};
}  // namespace std

extern Symbol kEmptySym;
extern Symbol kShellSym;
extern Symbol kKatiReadonlySym;

void InitSymtab();
void QuitSymtab();
Symbol Intern(StringPiece s);

string JoinSymbols(const vector<Symbol>& syms, const char* sep);

#endif  // SYMTAB_H_
