from base64 import b64decode
from bfs.bfs10131.errors import bfs10134
from bfs.bfs10076.bfs11057 import bfs11070, bfs11062
from datetime import date, datetime
from math import ceil, log
from os import path
from pkcs1 import rsaes_oaep
from pkcs1.keys import RsaPrivateKey
import logging
bfs10106 = logging.getLogger(__name__)
bfs10106.setLevel(logging.INFO)
bfs11073 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-/'
class bfs11072(object):
  bfs11074 = 32
  def __init__(self, bfs10213, code, bfs11075=None, encrypted_node_identifier='', bfs10210=True, is_online=True, bfs11077=False, bfs11076=None, bfs11100=None):
    self.bfs10213 = bfs10213
    self.code = code
    self.bfs11075 = bfs11075
    self.encrypted_node_identifier = encrypted_node_identifier
    self.bfs10210 = bfs10210
    self.is_online = is_online
    self.bfs11077 = bfs11077
    self.bfs11076 = bfs11076
    self.bfs11100 = bfs11100

  @property
  def bfs11102(self):
    if (not self.encrypted_node_identifier):
      return self.encrypted_node_identifier

    return self.decrypt(self.encrypted_node_identifier)

  @classmethod
  def decrypt(bfs11101, bfs11103):
    n = 126552595132100767496431298900695851144633929478317947845463894147101930730111564183119259440078050133900835449855213073742144369102834189244736695982848189036861833523332376016102290780726072320885243610990871511351145548702602510026707584848724238826408910261032648966390926399187028038467973734166869523139
    d = 47620634886441811911279006701406234418386824768677219155850665937740218712105852942916277172463872230223057250543653350192334441406304742984336354420144630234029397102707344769401491936717749314553261859131919096126529291266317948550850549782633820140042213874431692820120174629881124487475541748108487115593
    bfs11104 = RsaPrivateKey(n, d)
    return rsaes_oaep.decrypt(bfs11104, b64decode(bfs11103))

  def bfs11107(self, bfs11105=None):
    if (not self.bfs11077):
      return False

    return (self.bfs11076 < (date.today() if (bfs11105 is None) else bfs11105)
)

  def bfs11106(self):
    return bool(self.encrypted_node_identifier)

  def bfs11110(self, encrypted_node_identifier):
    try:
      self.decrypt(encrypted_node_identifier)
    except:
      raise ValueError(('Not a valid encrypted node identifier: %s' % encrypted_node_identifier))

    if self.bfs10210:
      self.encrypted_node_identifier = encrypted_node_identifier



class bfs11112(object):
  def __init__(self, file_path, bfs11111=None):
    if (bfs11111 is None):
      bfs11111 = []

    self.file_path = file_path
    self.bfs11111 = bfs11111

  def read(self):
    (bfs11113, key) = self.bfs11115()
    bfs11114 = bfs11116(self.bfs11111)
    bfs11117 = bfs11114.parse(bfs11113, key)
    bfs11117.bfs11075 = self.bfs11075
    return bfs11117

  def bfs11115(self):
    with open(self.file_path, 'r') as bfs11121:
      bfs11120 = bfs11121.readline().rstrip()
      key = bfs11121.readline().rstrip()
      if ((not bfs11120) or (not key)):
        raise bfs10134()

      return (bfs11120, key)


  def write(self, bfs11122):
    with open(self.file_path, 'w') as bfs11124:
      bfs11124.write((bfs11122.bfs10213 + '\n'))
      key = bfs11122.code
      if bfs11122.bfs10210:
        key += bfs11122.encrypted_node_identifier

      bfs11124.write((key + '\n'))


  def exists(self):
    return path.exists(self.file_path)

  @property
  def bfs11075(self):
    return datetime.fromtimestamp(path.getmtime(self.file_path))


class bfs11116(object):
  def __init__(self, bfs11111=None):
    if (bfs11111 is None):
      bfs11111 = []

    self.bfs11111 = bfs11111

  def parse(self, bfs11123, key):
    code = key[:bfs11072.bfs11074]
    bfs11125 = key[bfs11072.bfs11074:]
    try:
      if (code in self.bfs11111):
        return self.bfs11127(bfs11123, code, bfs11125)
      else:
        return self.bfs11126(bfs11123, code, bfs11125)

    except ValueError:
      return bfs11072(bfs11123, code, encrypted_node_identifier=bfs11125)


  def bfs11127(self, bfs11130, code, encrypted_node_identifier):
    bfs11131 = True
    is_online = True
    bfs11132 = False
    bfs11134 = None
    try:
      bfs11133 = int(code[:1])
    except ValueError:
      bfs11133 = None

    return bfs11072(bfs11130, code, None, encrypted_node_identifier, bfs11131, is_online, bfs11132, bfs11134, bfs11133)

  def bfs11126(self, bfs11135, code, encrypted_node_identifier):
    bfs11137 = bfs11136(code)
    bfs10210 = bfs11137.bfs10210
    is_online = bfs11137.is_online
    bfs11077 = bfs11137.bfs11077
    bfs11076 = bfs11137.bfs11076
    bfs11100 = bfs11137.bfs11100
    return bfs11072(bfs11135, code, None, encrypted_node_identifier, bfs10210, is_online, bfs11077, bfs11076, bfs11100)


class bfs11140:
  bfs11141 = 0
  bfs11142 = 1
  bfs11143 = 2
  bfs11144 = 3
  bfs11146 = 4
  bfs11145 = 5
  bfs11147 = 6

class bfs11136(object):
  bfs11150 = [(bfs11140.bfs11141, 5), (bfs11140.bfs11142, 1), (bfs11140.bfs11143, 1), (bfs11140.bfs11144, 1), (bfs11140.bfs11146, 7), (bfs11140.bfs11145, 4), (bfs11140.bfs11147, 5)]
  def __init__(self, code):
    self.code = code
    bfs11151 = self.bfs11152(self.code)
    self.bfs11100 = self.bfs11154(bfs11151, bfs11140.bfs11141)
    self.is_online = (self.bfs11154(bfs11151, bfs11140.bfs11142) > 0)
    self.bfs10210 = (self.bfs11154(bfs11151, bfs11140.bfs11143) > 0)
    self.bfs11077 = (self.bfs11154(bfs11151, bfs11140.bfs11144) > 0)
    bfs11076 = None
    if self.bfs11077:
      bfs11153 = (2000 + self.bfs11154(bfs11151, bfs11140.bfs11146))
      bfs11155 = self.bfs11154(bfs11151, bfs11140.bfs11145)
      bfs11156 = self.bfs11154(bfs11151, bfs11140.bfs11147)
      bfs11076 = date(bfs11153, bfs11155, bfs11156)

    self.bfs11076 = bfs11076

  def bfs11152(self, text):
    bfs11157 = 6
    assert (len(bfs11073) == (2 ** bfs11157))
    bfs11161 = ''
    for bfs11160 in text:
      bfs11162 = bfs11062(bfs11070(bfs11160, bfs11073), '01')
      while (len(bfs11162) < bfs11157):
        bfs11162 = ('0' + bfs11162)

      bfs11161 += bfs11162

    bfs11163 = (len(text) * bfs11157)
    bfs11165 = int(ceil((log(bfs11163) / log(2))))
    bfs11164 = bfs11161[:bfs11165]
    bfs11166 = bfs11070(bfs11164, '01')
    return bfs11161[bfs11165:(bfs11165 + bfs11166)]

  def bfs11154(self, bfs11170, bfs11167):
    offset = 0
    (bfs11171, bfs11173) = list(zip(*self.bfs11150))
    bfs11172 = bfs11171.index(bfs11167)
    for index in range(0, bfs11172):
      offset += bfs11173[index]

    if (len(bfs11170) <= offset):
      return (-1)

    return bfs11070(bfs11170[offset:(offset + bfs11173[bfs11171.index(bfs11167)])], '01')


