from base64 import b64decode
from bfs.bfs10135.errors import bfs10137
from bfs.bfs10077.bfs11053 import bfs11064, bfs11056
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
bfs10107 = logging.getLogger(__name__)
bfs10107.setLevel(logging.INFO)
bfs11065 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-/'
class bfs11067(object):
  bfs11066 = 32
  def __init__(self, bfs10214, code, bfs11070=None, encrypted_node_identifier='', bfs10211=True, is_online=True, bfs11071=False, bfs11073=None, bfs11072=None):
    self.bfs10214 = bfs10214
    self.code = code
    self.bfs11070 = bfs11070
    self.encrypted_node_identifier = encrypted_node_identifier
    self.bfs10211 = bfs10211
    self.is_online = is_online
    self.bfs11071 = bfs11071
    self.bfs11073 = bfs11073
    self.bfs11072 = bfs11072

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

    return self.decrypt(self.encrypted_node_identifier)

  @classmethod
  def decrypt(bfs11075, bfs11077):
    n = 126552595132100767496431298900695851144633929478317947845463894147101930730111564183119259440078050133900835449855213073742144369102834189244736695982848189036861833523332376016102290780726072320885243610990871511351145548702602510026707584848724238826408910261032648966390926399187028038467973734166869523139
    d = 47620634886441811911279006701406234418386824768677219155850665937740218712105852942916277172463872230223057250543653350192334441406304742984336354420144630234029397102707344769401491936717749314553261859131919096126529291266317948550850549782633820140042213874431692820120174629881124487475541748108487115593
    bfs11076 = RsaPrivateKey(n, d)
    return rsaes_oaep.decrypt(bfs11076, b64decode(bfs11077))

  def bfs11102(self, bfs11100=None):
    if (not self.bfs11071):
      return False

    return (self.bfs11073 < (date.today() if (bfs11100 is None) else bfs11100)
)

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

  def bfs11103(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.bfs10211:
      self.encrypted_node_identifier = encrypted_node_identifier



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

    self.file_path = file_path
    self.bfs11105 = bfs11105

  def read(self):
    (bfs11107, key) = self.bfs11106()
    bfs11110 = bfs11112(self.bfs11105)
    bfs11111 = bfs11110.parse(bfs11107, key)
    bfs11111.bfs11070 = self.bfs11070
    return bfs11111

  def bfs11106(self):
    with open(self.file_path, 'r') as bfs11113:
      bfs11115 = bfs11113.readline().rstrip()
      key = bfs11113.readline().rstrip()
      if ((not bfs11115) or (not key)):
        raise bfs10137()

      return (bfs11115, key)


  def write(self, bfs11114):
    with open(self.file_path, 'w') as bfs11116:
      bfs11116.write((bfs11114.bfs10214 + '\n'))
      key = bfs11114.code
      if bfs11114.bfs10211:
        key += bfs11114.encrypted_node_identifier

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


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

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


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

    self.bfs11105 = bfs11105

  def parse(self, bfs11117, key):
    code = key[:bfs11067.bfs11066]
    bfs11121 = key[bfs11067.bfs11066:]
    try:
      if (code in self.bfs11105):
        return self.bfs11120(bfs11117, code, bfs11121)
      else:
        return self.bfs11122(bfs11117, code, bfs11121)

    except ValueError:
      return bfs11067(bfs11117, code, encrypted_node_identifier=bfs11121)


  def bfs11120(self, bfs11124, code, encrypted_node_identifier):
    bfs11123 = True
    is_online = True
    bfs11125 = False
    bfs11127 = None
    try:
      bfs11126 = int(code[:1])
    except ValueError:
      bfs11126 = None

    return bfs11067(bfs11124, code, None, encrypted_node_identifier, bfs11123, is_online, bfs11125, bfs11127, bfs11126)

  def bfs11122(self, bfs11130, code, encrypted_node_identifier):
    bfs11131 = bfs11132(code)
    bfs10211 = bfs11131.bfs10211
    is_online = bfs11131.is_online
    bfs11071 = bfs11131.bfs11071
    bfs11073 = bfs11131.bfs11073
    bfs11072 = bfs11131.bfs11072
    return bfs11067(bfs11130, code, None, encrypted_node_identifier, bfs10211, is_online, bfs11071, bfs11073, bfs11072)


class bfs11134:
  bfs11133 = 0
  bfs11135 = 1
  bfs11137 = 2
  bfs11136 = 3
  bfs11140 = 4
  bfs11141 = 5
  bfs11142 = 6

class bfs11132(object):
  bfs11143 = [(bfs11134.bfs11133, 5), (bfs11134.bfs11135, 1), (bfs11134.bfs11137, 1), (bfs11134.bfs11136, 1), (bfs11134.bfs11140, 7), (bfs11134.bfs11141, 4), (bfs11134.bfs11142, 5)]
  def __init__(self, code):
    self.code = code
    bfs11144 = self.bfs11146(self.code)
    self.bfs11072 = self.bfs11145(bfs11144, bfs11134.bfs11133)
    self.is_online = (self.bfs11145(bfs11144, bfs11134.bfs11135) > 0)
    self.bfs10211 = (self.bfs11145(bfs11144, bfs11134.bfs11137) > 0)
    self.bfs11071 = (self.bfs11145(bfs11144, bfs11134.bfs11136) > 0)
    bfs11073 = None
    if self.bfs11071:
      bfs11147 = (2000 + self.bfs11145(bfs11144, bfs11134.bfs11140))
      bfs11150 = self.bfs11145(bfs11144, bfs11134.bfs11141)
      bfs11151 = self.bfs11145(bfs11144, bfs11134.bfs11142)
      bfs11073 = date(bfs11147, bfs11150, bfs11151)

    self.bfs11073 = bfs11073

  def bfs11146(self, text):
    bfs11152 = 6
    assert (len(bfs11065) == (2 ** bfs11152))
    bfs11154 = ''
    for bfs11153 in text:
      bfs11155 = bfs11056(bfs11064(bfs11153, bfs11065), '01')
      while (len(bfs11155) < bfs11152):
        bfs11155 = ('0' + bfs11155)

      bfs11154 += bfs11155

    bfs11156 = (len(text) * bfs11152)
    bfs11157 = int(ceil((log(bfs11156) / log(2))))
    bfs11161 = bfs11154[:bfs11157]
    bfs11160 = bfs11064(bfs11161, '01')
    return bfs11154[bfs11157:(bfs11157 + bfs11160)]

  def bfs11145(self, bfs11162, bfs11163):
    offset = 0
    (bfs11165, bfs11164) = list(zip(*self.bfs11143))
    bfs11166 = bfs11165.index(bfs11163)
    for index in range(0, bfs11166):
      offset += bfs11164[index]

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

    return bfs11064(bfs11162[offset:(offset + bfs11164[bfs11165.index(bfs11163)])], '01')


