#pragma once

#ifndef PASSWORD_HPP
  #define PASSWORD_HPP

  #include <cstdint>
  #include <string>
  #include <string_view>

  #include "locked_buffer.hpp"

namespace sec {

enum class strength_t : uint8_t {
  very_weak = 0,
  weak,
  moderate,
  strong,
  very_strong
};

class password_hash;

class password {
public:
  explicit password(std::string pass);

  std::string_view view() const noexcept;

  static sec::password from_console();
  static sec::password from_string(const std::string &pass);

  sec::password_hash to_hash() const;

private:
  sec::locked_buffer<char, 128> _buf;
  std::size_t _len{};
};

class password_hash {
public:
  explicit password_hash(std::string hash);
  const std::string &get() const noexcept;

  bool verify(const sec::password &pwd) const;

private:
  std::string _hash;
};

class manager {
public:
  static bool has_lower(const sec::password &pwd);
  static bool has_upper(const sec::password &pwd);
  static bool has_digit(const sec::password &pwd);
  static bool has_spec_symbol(const sec::password &pwd);

  static std::string hash_password(const sec::password &pwd);
  static sec::strength_t evaluate_strength(const sec::password &pwd);
  static uint64_t time_to_crack(const sec::password &pwd);
  static std::string format_duration(uint64_t seconds);
};

} // namespace sec

  #include "../src/password.cpp"

#endif
