from base64 import b64decode
from bfs.bfs10131.errors import bfs10134
from bfs.bfs10076.bfs11061 import bfs11071, bfs11064
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)
bfs11072 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-/'
class bfs11074(object):
  bfs11075 = 32
  def __init__(self, bfs10213, code, bfs11077=None, encrypted_node_identifier='', bfs10210=True, is_online=True, bfs11076=False, bfs11100=None, bfs11102=None):
    self.bfs10213 = bfs10213
    self.code = code
    self.bfs11077 = bfs11077
    self.encrypted_node_identifier = encrypted_node_identifier
    self.bfs10210 = bfs10210
    self.is_online = is_online
    self.bfs11076 = bfs11076
    self.bfs11100 = bfs11100
    self.bfs11102 = bfs11102

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

    return self.decrypt(self.encrypted_node_identifier)

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

  def bfs11106(self, bfs11107=None):
    if (not self.bfs11076):
      return False

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

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

  def bfs11112(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 bfs11111(object):
  def __init__(self, file_path, bfs11113=None):
    if (bfs11113 is None):
      bfs11113 = []

    self.file_path = file_path
    self.bfs11113 = bfs11113

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

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

      return (bfs11122, key)


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

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


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

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


class bfs11117(object):
  def __init__(self, bfs11113=None):
    if (bfs11113 is None):
      bfs11113 = []

    self.bfs11113 = bfs11113

  def parse(self, bfs11125, key):
    code = key[:bfs11074.bfs11075]
    bfs11127 = key[bfs11074.bfs11075:]
    try:
      if (code in self.bfs11113):
        return self.bfs11126(bfs11125, code, bfs11127)
      else:
        return self.bfs11130(bfs11125, code, bfs11127)

    except ValueError:
      return bfs11074(bfs11125, code, encrypted_node_identifier=bfs11127)


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

    return bfs11074(bfs11131, code, None, encrypted_node_identifier, bfs11132, is_online, bfs11134, bfs11133, bfs11135)

  def bfs11130(self, bfs11137, code, encrypted_node_identifier):
    bfs11136 = bfs11140(code)
    bfs10210 = bfs11136.bfs10210
    is_online = bfs11136.is_online
    bfs11076 = bfs11136.bfs11076
    bfs11100 = bfs11136.bfs11100
    bfs11102 = bfs11136.bfs11102
    return bfs11074(bfs11137, code, None, encrypted_node_identifier, bfs10210, is_online, bfs11076, bfs11100, bfs11102)


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

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

    self.bfs11100 = bfs11100

  def bfs11154(self, text):
    bfs11161 = 6
    assert (len(bfs11072) == (2 ** bfs11161))
    bfs11160 = ''
    for bfs11162 in text:
      bfs11163 = bfs11064(bfs11071(bfs11162, bfs11072), '01')
      while (len(bfs11163) < bfs11161):
        bfs11163 = ('0' + bfs11163)

      bfs11160 += bfs11163

    bfs11165 = (len(text) * bfs11161)
    bfs11164 = int(ceil((log(bfs11165) / log(2))))
    bfs11166 = bfs11160[:bfs11164]
    bfs11170 = bfs11071(bfs11166, '01')
    return bfs11160[bfs11164:(bfs11164 + bfs11170)]

  def bfs11153(self, bfs11167, bfs11171):
    offset = 0
    (bfs11173, bfs11172) = zip(*self.bfs11151)
    bfs11174 = bfs11173.index(bfs11171)
    for index in range(0, bfs11174):
      offset += bfs11172[index]

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

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


