// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Implements shill::CellularOperatorInfo. See cellular_operator_info.h for
// details.

#include "shill/cellular_operator_info.h"

#include <base/stl_util.h>
#include <base/string_number_conversions.h>
#include <base/string_split.h>
#include <base/string_util.h>

#include "shill/logging.h"

using base::FilePath;
using std::map;
using std::string;
using std::vector;

namespace shill {

namespace {

typedef vector<const CellularOperatorInfo::CellularOperator *>
    ConstOperatorVector;

string FormattedMCCMNC(const string &mccmnc) {
  return "[MCCMNC=" + mccmnc + "]";
}

string FormattedSID(const string &sid) {
  return "[SID=" + sid + "]";
}

template <class Collection>
const typename Collection::value_type::second_type *FindOrNull(
    const Collection &collection,
    const typename Collection::value_type::first_type &key) {
  typename Collection::const_iterator it = collection.find(key);
  if (it == collection.end())
    return NULL;
  return &it->second;
}

typedef CellularOperatorInfo COI;
bool ParseNameLine(const string &value, COI::LocalizedName *name) {
  vector<string> fields;
  base::SplitString(value, ',', &fields);
  if (fields.size() != 2) {
    LOG(ERROR) << "Badly formed \"name\" entry.";
    return false;
  }
  name->language = fields[0];
  name->name = fields[1];
  return true;
}

// Advances the file reader to the next line that is neither a line comment
// nor empty and returns it in |line|. If the end of file is reached, returns
// false.
bool AdvanceToNextValidLine(FileReader &file_reader, string *line) {
  while (file_reader.ReadLine(line)) {
    TrimWhitespaceASCII(*line, TRIM_ALL, line);
    // Skip line comments.
    if ((*line)[0] == '#' || line->empty())
      continue;
    // If line consists of a single null character, skip
    if (line->length() == 1 && (*line)[0] == '\0')
      continue;
    return true;
  }
  return false;
}

// Splits |line| into two strings, separated with the |key_value_delimiter|.
// Returns |false| if line does not contain |key_value_delimiter|, otherwise
// returns the first substring in |key| and the second substring in |value|,
// and returns true.
bool ParseKeyValue(const string &line,
                   char key_value_delimiter,
                   std::string *key,
                   std::string *value) {
  const size_t length = line.length();
  for (size_t i = 0; i < length; ++i) {
    if (line[i] == key_value_delimiter) {
      key->assign(line, 0, i);
      value->assign(line, i + 1, length-i);
      return true;
    }
  }
  LOG(ERROR) << "Badly formed line: " << line;
  return false;
}

}  // namespace

class CellularOperatorInfoImpl {
 public:
  CellularOperatorInfoImpl() {
    key_to_handler_["provider"] = new ProviderHandler(this);
    key_to_handler_["mccmnc"] = new MccmncHandler(this);
    key_to_handler_["name"] = new NameHandler(this);
    key_to_handler_["apn"] = new ApnHandler(this);
    key_to_handler_["sid"] = new SidHandler(this);
    key_to_handler_["olp"] = new OlpHandler(this);
    key_to_handler_["identifier"] = new IdentifierHandler(this);
    key_to_handler_["activation-code"] = new ActivationCodeHandler(this);
    key_to_handler_["country"] = new CountryHandler(this);
  }

  ~CellularOperatorInfoImpl() {
    STLDeleteContainerPairSecondPointers(key_to_handler_.begin(),
                                         key_to_handler_.end());
  }

 private:
  struct ParserState {
    ParserState() : provider(NULL), apn(NULL), parsing_apn(false) {}

    void Clear() {
      country.clear();
      provider = NULL;
      apn = NULL;
      parsing_apn = false;
    }

    std::string country;
    COI::CellularOperator *provider;
    COI::MobileAPN *apn;

    bool parsing_apn;
  };

  class KeyHandler {
   public:
    KeyHandler(CellularOperatorInfoImpl *info_impl) : info_impl_(info_impl) {}
    virtual ~KeyHandler() {}

    virtual bool HandleKey(const string &value) = 0;

   protected:
    CellularOperatorInfoImpl *info_impl() const { return info_impl_; }

   private:
    CellularOperatorInfoImpl *info_impl_;

    DISALLOW_COPY_AND_ASSIGN(KeyHandler);
  };

  class CountryHandler : public KeyHandler {
   public:
    CountryHandler(CellularOperatorInfoImpl *info_impl)
        : KeyHandler(info_impl) {}

    bool HandleKey(const string &value) {
      return info_impl()->HandleCountry(value);
    }

   private:
    DISALLOW_COPY_AND_ASSIGN(CountryHandler);
  };

  class NameHandler : public KeyHandler {
   public:
    NameHandler(CellularOperatorInfoImpl *info_impl)
        : KeyHandler(info_impl) {}

    bool HandleKey(const string &value) {
      return info_impl()->HandleNameKey(value);
    }

   private:
    DISALLOW_COPY_AND_ASSIGN(NameHandler);
  };

  class ProviderHandler : public KeyHandler {
   public:
    ProviderHandler(CellularOperatorInfoImpl *info_impl)
        : KeyHandler(info_impl) {}

    bool HandleKey(const string &value) {
      return info_impl()->HandleProvider(value);
    }

   private:
    DISALLOW_COPY_AND_ASSIGN(ProviderHandler);
  };

  class MccmncHandler : public KeyHandler {
   public:
    MccmncHandler(CellularOperatorInfoImpl *info_impl)
        : KeyHandler(info_impl) {}

    bool HandleKey(const string &value) {
      return info_impl()->HandleMCCMNC(value);
    }

   private:
    DISALLOW_COPY_AND_ASSIGN(MccmncHandler);
  };

  class IdentifierHandler : public KeyHandler {
   public:
    IdentifierHandler(CellularOperatorInfoImpl *info_impl)
        : KeyHandler(info_impl) {}

    bool HandleKey(const string &value) {
      return info_impl()->HandleIdentifier(value);
    }

   private:
    DISALLOW_COPY_AND_ASSIGN(IdentifierHandler);
  };

  class ActivationCodeHandler : public KeyHandler {
   public:
    ActivationCodeHandler(CellularOperatorInfoImpl *info_impl)
       : KeyHandler(info_impl) {}

    bool HandleKey(const string &value) {
      return info_impl()->HandleActivationCode(value);
    }

   private:
    DISALLOW_COPY_AND_ASSIGN(ActivationCodeHandler);
  };

  class ApnHandler : public KeyHandler {
   public:
    ApnHandler(CellularOperatorInfoImpl *info_impl)
        : KeyHandler(info_impl) {}

    bool HandleKey(const string &value) {
      return info_impl()->HandleAPN(value);
    }

   private:
    DISALLOW_COPY_AND_ASSIGN(ApnHandler);
  };

  class SidHandler : public KeyHandler {
   public:
    SidHandler(CellularOperatorInfoImpl *info_impl)
        : KeyHandler(info_impl) {}

    bool HandleKey(const string &value) {
      return info_impl()->HandleSID(value);
    }

   private:
    DISALLOW_COPY_AND_ASSIGN(SidHandler);
  };

  class OlpHandler : public KeyHandler {
   public:
    OlpHandler(CellularOperatorInfoImpl *info_impl)
        : KeyHandler(info_impl) {}

    bool HandleKey(const string &value) {
      return info_impl()->HandleOLP(value);
    }

   private:
    DISALLOW_COPY_AND_ASSIGN(OlpHandler);
  };

  bool HandleFirstLine(FileReader &reader) {
    // Read until the first line that is not a line comment.
    string line;
    if (!AdvanceToNextValidLine(reader, &line))
      return false;

    string key, value;
    if (!ParseKeyValue(line, ':', &key, &value))
      return false;

    if (key != "serviceproviders") {
      LOG(ERROR) << "File does not begin with \"serviceproviders\" "
                 << "entry.";
      return false;
    }
    if (value != "3.0") {
      LOG(ERROR) << "Unrecognized serviceproviders format.";
      return false;
    }
    return true;
  }

  bool HandleCountry(const string &value) {
    state_.country = value;
    return true;
  }

  bool HandleNameKey(const string &value) {
    if (state_.parsing_apn)
      return HandleAPNName(value);
    return HandleName(value);
  }

  bool HandleProvider(const string &value) {
    state_.parsing_apn = false;

    vector<string> fields;
    base::SplitString(value, ',', &fields);
    if (fields.size() != 4) {
      LOG(ERROR) << "Badly formed \"provider\" entry.";
      return false;
    }

    int is_primary = 0;
    if (!base::StringToInt(fields[2], &is_primary)) {
      LOG(ERROR) << "Badly formed value for \"is_primary\": " << fields[2];
      return false;
    }
    int requires_roaming = 0;
    if (!base::StringToInt(fields[3], &requires_roaming)) {
      LOG(ERROR) << "Badly formed value for \"requires_roaming\": "
                 << fields[3];
      return false;
    }
    state_.provider = new COI::CellularOperator();
    state_.provider->is_primary_ = is_primary != 0;
    state_.provider->requires_roaming_ = requires_roaming != 0;
    state_.provider->country_ = state_.country;

    operators_.push_back(state_.provider);
    return true;
  }

  bool HandleMCCMNC(const string &value) {
    if (value.empty()) {
      LOG(ERROR) << "Empty \"mccmnc\" value.";
      return false;
    }
    if (!state_.provider) {
      LOG(ERROR) << "Found \"mccmnc\" entry without \"provider\".";
      return false;
    }

    vector<string> mccmnc_list;
    base::SplitString(value, ',', &mccmnc_list);
    if ((mccmnc_list.size() % 2) != 0) {
      LOG(ERROR) << "Badly formatted \"mccmnc\" entry. "
                 << "Expected even number of elements.";
      return false;
    }

    for (size_t i = 0; i < mccmnc_list.size(); i += 2) {
      const string &mccmnc = mccmnc_list[i];
      if (!mccmnc.empty()) {
        state_.provider->mccmnc_list_.push_back(mccmnc);
        mccmnc_to_operator_[mccmnc] = state_.provider;
        int index = -1;
        if (base::StringToInt(mccmnc_list[i + 1], &index))
          state_.provider->mccmnc_to_olp_idx_[mccmnc] = index;
      }
    }
    return true;
  }

  bool HandleIdentifier(const string &value) {
    if (!state_.provider) {
      LOG(ERROR) << "Found \"identifier\" entry without \"provider\".";
      return false;
    }
    state_.provider->identifier_ = value;
    return true;
  }

  bool HandleActivationCode(const string &value) {
    if (!state_.provider) {
      LOG(ERROR) << "Found \"activation-code\" entry without \"provider\".";
      return false;
    }
    state_.provider->activation_code_ = value;
    return true;
  }

  bool HandleAPN(const string &value) {
    if (!state_.provider) {
      LOG(ERROR) << "Found \"apn\" entry without \"provider\".";
      return false;
    }
    vector<string> fields;
    base::SplitString(value, ',', &fields);
    if (fields.size() != 4) {
      LOG(ERROR) << "Badly formed \"apn\" entry.";
      return false;
    }
    state_.apn = new COI::MobileAPN();
    state_.apn->apn = fields[1];
    state_.apn->username = fields[2];
    state_.apn->password = fields[3];
    state_.provider->apn_list_.push_back(state_.apn);
    state_.parsing_apn = true;
    return true;
  }

  bool HandleAPNName(const string &value) {
    if (!(state_.parsing_apn && state_.apn)) {
      LOG(ERROR) << "APN not being parsed.";
      return false;
    }
    COI::LocalizedName name;
    if (!ParseNameLine(value, &name))
      return false;
    state_.apn->name_list.push_back(name);
    return true;
  }

  bool HandleName(const string &value) {
    if (!state_.provider) {
      LOG(ERROR) << "Found \"name\" entry without \"provider\".";
      return false;
    }

    COI::LocalizedName name;
    if (!ParseNameLine(value, &name))
      return false;

    if (state_.provider->name_list_.size() == 0) {
      ConstOperatorVector &matching_operators =
          name_to_operators_[name.name];
      matching_operators.push_back(state_.provider);
    }
    state_.provider->name_list_.push_back(name);
    return true;
  }

  bool HandleSID(const string &value) {
    if (value.empty()) {
      LOG(ERROR) << "Empty \"sid\" value.";
      return false;
    }
    if (!state_.provider) {
      LOG(ERROR) << "Found \"sid\" entry without \"provider\".";
      return false;
    }
    vector<string> sid_list;
    base::SplitString(value, ',', &sid_list);
    if ((sid_list.size() % 2) != 0) {
      LOG(ERROR) << "Badly formatted \"sid\" entry. "
                 << "Expected even number of elements. ";
      return false;
    }

    for (size_t i = 0; i < sid_list.size(); i += 2) {
      const string &sid = sid_list[i];
      if (!sid.empty()) {
        state_.provider->sid_list_.push_back(sid);
        sid_to_operator_[sid] = state_.provider;
        int index = -1;
        if (base::StringToInt(sid_list[i + 1], &index))
          state_.provider->sid_to_olp_idx_[sid] = index;
      }
    }
    return true;
  }

  bool HandleOLP(const string &value) {
    if (!state_.provider) {
      LOG(ERROR) << "Found \"olp\" entry without \"provider\"";
      return false;
    }
    vector<string> fields;
    base::SplitString(value, ',', &fields);
    if (fields.size() != 3) {
      LOG(ERROR) << "Badly formed \"apn\" entry.";
      return false;
    }
    CellularService::OLP *olp = new CellularService::OLP();
    olp->SetMethod(fields[0]);
    olp->SetURL(fields[1]);
    olp->SetPostData(fields[2]);

    state_.provider->olp_list_.push_back(olp);
    return true;
  }

  void ClearOperators() {
    operators_.clear();
    mccmnc_to_operator_.clear();
    sid_to_operator_.clear();
    name_to_operators_.clear();
  }

  bool HandleKeyValue(const string &key, const string &value) {
    KeyHandler * const *handler = FindOrNull(key_to_handler_, key);
    if (!handler) {
      LOG(ERROR) << "Invalid key \"" << key << "\".";
      return false;
    }
    return (*handler)->HandleKey(value);
  }

  bool Load(const FilePath &info_file_path) {
    // Clear any previus operators.
    ClearOperators();

    FileReader file_reader;
    if (!file_reader.Open(info_file_path)) {
      LOG(ERROR) << "Could not open operator info file.";
      return false;
    }

    // See data/cellular_operator_info for the format of file contents.

    state_.Clear();

    if (!HandleFirstLine(file_reader))
      return false;

    string line;
    while (true) {
      if (!AdvanceToNextValidLine(file_reader, &line))
        break;

      string key, value;
      if (!ParseKeyValue(line, ':', &key, &value)) {
        ClearOperators();
        return false;
      }

      if (!HandleKeyValue(key, value)) {
        LOG(ERROR) << "Failed to parse \"" << key << "\" entry.";
        ClearOperators();
        return false;
      }
    }
    return true;
  }

 private:
  friend class CellularOperatorInfo;

  ParserState state_;

  ScopedVector<COI::CellularOperator> operators_;
  map<string, COI::CellularOperator *> mccmnc_to_operator_;
  map<string, COI::CellularOperator *> sid_to_operator_;
  map<string, ConstOperatorVector> name_to_operators_;

  map<string, KeyHandler *> key_to_handler_;

  DISALLOW_COPY_AND_ASSIGN(CellularOperatorInfoImpl);
};

COI::LocalizedName::LocalizedName() {}
COI::LocalizedName::LocalizedName(string name,
                                  string language)
    : name(name),
      language(language) {}

CellularOperatorInfo::CellularOperator::CellularOperator()
    : is_primary_(false),
      requires_roaming_(false) {}

CellularOperatorInfo::CellularOperatorInfo()
    : impl_(new CellularOperatorInfoImpl()) {}
CellularOperatorInfo::~CellularOperatorInfo() {}

const ScopedVector<CellularOperatorInfo::CellularOperator> &
CellularOperatorInfo::operators() const {
  return impl_->operators_;
}

const CellularOperatorInfo::CellularOperator *
CellularOperatorInfo::GetCellularOperatorByMCCMNC(const string &mccmnc) const {
  SLOG(Cellular, 2) << __func__ << "(" << FormattedMCCMNC(mccmnc) << ")";

  CellularOperator * const *provider =
      FindOrNull(impl_->mccmnc_to_operator_, mccmnc);
  if (!provider) {
    LOG(ERROR) << "Operator with " << FormattedMCCMNC(mccmnc)
               << " not found.";
    return NULL;
  }
  return *provider;
}

const CellularOperatorInfo::CellularOperator *
CellularOperatorInfo::GetCellularOperatorBySID(const string &sid) const {
  SLOG(Cellular, 2) << __func__ << "(" << FormattedSID(sid) << ")";

  CellularOperator * const *provider = FindOrNull(impl_->sid_to_operator_, sid);
  if (!provider) {
    LOG(ERROR) << "Operator with " << FormattedSID(sid) << " not found.";
    return NULL;
  }
  return *provider;
}

const ConstOperatorVector *CellularOperatorInfo::GetCellularOperators(
    const string &name) const {
  SLOG(Cellular, 2) << __func__ << "(" << name << ")";

  const ConstOperatorVector *providers =
      FindOrNull(impl_->name_to_operators_, name);
  if (!providers) {
    LOG(ERROR) << "Given name \"" << name << "\" did not match any operators.";
    return NULL;
  }
  return providers;
}

const CellularService::OLP *
CellularOperatorInfo::GetOLPByMCCMNC(const string &mccmnc) const {
  SLOG(Cellular, 2) << __func__ << "(" << FormattedMCCMNC(mccmnc) << ")";

  const CellularOperator *provider = GetCellularOperatorByMCCMNC(mccmnc);
  if (!provider)
    return NULL;

  const uint32 *indexptr = FindOrNull(provider->mccmnc_to_olp_idx_, mccmnc);
  if (!indexptr)
    return NULL;

  uint32 index = *indexptr;
  if (index >= provider->olp_list_.size()) {
    LOG(ERROR) << "Invalid OLP index found for "
               << FormattedMCCMNC(mccmnc) << ".";
    return NULL;
  }

  return provider->olp_list_[index];
}

const CellularService::OLP *
CellularOperatorInfo::GetOLPBySID(const string &sid) const {
  SLOG(Cellular, 2) << __func__ << "(" << FormattedSID(sid) << ")";

  const CellularOperator *provider = GetCellularOperatorBySID(sid);
  if (!provider)
    return NULL;

  const uint32 *indexptr = FindOrNull(provider->sid_to_olp_idx_, sid);
  if (!indexptr)
    return NULL;

  uint32 index = *indexptr;
  if (index >= provider->olp_list_.size()) {
    LOG(ERROR) << "Invalid OLP index found for " << FormattedSID(sid) << ".";
    return NULL;
  }

  return provider->olp_list_[index];
}

bool CellularOperatorInfo::Load(const FilePath &info_file_path) {
  SLOG(Cellular, 2) << __func__ << "(" << info_file_path.value() << ")";
  return impl_->Load(info_file_path);
}

}  // namespace shill
