/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

#include <iostream>
#include <regex>  // NOLINT
#include <string>

#include "graphar/util/version_parser.h"

namespace graphar {

// Helper function for parsing version string
bool is_whitespace(char ch) {
  return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n';
}

void trim(std::string& s) {  // NOLINT
  size_t trim_left = 0;
  for (auto it = s.begin(); it != s.end(); ++it) {
    if (!is_whitespace(*it)) {
      break;
    }
    ++trim_left;
  }

  if (trim_left == s.size()) {
    s.clear();
  } else {
    size_t trim_right = 0;
    for (auto it = s.rbegin(); it != s.rend(); ++it) {
      if (!is_whitespace(*it)) {
        break;
      }
      ++trim_right;
    }

    if (trim_left > 0 || trim_right > 0) {
      if (trim_left == 0) {
        s.resize(s.size() - trim_right);
      } else {
        std::string copy(s.c_str() + trim_left,
                         s.size() - trim_left - trim_right);
        s.swap(copy);
      }
    }
  }
}

int parserVersionImpl(const std::string& version_str) {
  std::smatch match;
  const std::regex version_regex("gar/v(\\d+).*");
  if (std::regex_match(version_str, match, version_regex)) {
    if (match.size() != 2) {
      throw std::runtime_error("Invalid version string: " + version_str);
    }
    return std::stoi(match[1].str());
  } else {
    throw std::runtime_error("Invalid version string: " + version_str);
  }
}

std::vector<std::string> parseUserDefineTypesImpl(
    const std::string& version_str) {
  std::smatch match;
  std::vector<std::string> user_define_types;
  const std::regex user_define_types_regex("gar/v\\d+ *\\((.*)\\).*");
  if (std::regex_match(version_str, match, user_define_types_regex)) {
    if (match.size() != 2) {
      throw std::runtime_error("Invalid version string: " + version_str);
    }
    std::string types_str = match[1].str();
    size_t pos = 0;
    while (pos != std::string::npos) {
      size_t next_pos = types_str.find(',', pos);
      std::string type = types_str.substr(pos, next_pos - pos);
      trim(type);
      if (!type.empty()) {
        user_define_types.push_back(type);
      }
      if (next_pos != std::string::npos) {
        pos = next_pos + 1;
      } else {
        pos = next_pos;
      }
    }
  }
  return user_define_types;
}

Result<std::shared_ptr<const InfoVersion>> InfoVersion::Parse(
    const std::string& version_str) noexcept {
  std::shared_ptr<InfoVersion> version;
  try {
    version = std::make_shared<InfoVersion>(
        parserVersionImpl(version_str), parseUserDefineTypesImpl(version_str));
  } catch (const std::exception& e) {
    return Status::Invalid("Invalid version string: ", version_str);
  }
  return version;
}
}  // namespace graphar
