from base64 import b64decode
from bfs.bfs10110.bfs10112 import InvalidLicenseFile
from bfs.bfs10063.bfs11044 import bfs11056, bfs11046
from datetime import date, datetime
from math import ceil, log
from os import path
from pkcs1 import rsaes_oaep
from pkcs1.keys import RsaPrivateKey
bfs11057 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-/'
class bfs11061(object):
  bfs11060 = 32
  def __init__(self, bfs10166, code, bfs11062=None, encrypted_node_identifier='', bfs10162=True, is_online=True, bfs11064=False, bfs11063=None, bfs11065=None):
    self.bfs10166 = bfs10166
    self.code = code
    self.bfs11062 = bfs11062
    self.encrypted_node_identifier = encrypted_node_identifier
    self.bfs10162 = bfs10162
    self.is_online = is_online
    self.bfs11064 = bfs11064
    self.bfs11063 = bfs11063
    self.bfs11065 = bfs11065

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

    return self.decrypt(self.encrypted_node_identifier)

  @classmethod
  def decrypt(bfs11066, bfs11070):
    n = 126552595132100767496431298900695851144633929478317947845463894147101930730111564183119259440078050133900835449855213073742144369102834189244736695982848189036861833523332376016102290780726072320885243610990871511351145548702602510026707584848724238826408910261032648966390926399187028038467973734166869523139
    d = 47620634886441811911279006701406234418386824768677219155850665937740218712105852942916277172463872230223057250543653350192334441406304742984336354420144630234029397102707344769401491936717749314553261859131919096126529291266317948550850549782633820140042213874431692820120174629881124487475541748108487115593
    bfs11071 = RsaPrivateKey(n, d)
    return rsaes_oaep.decrypt(bfs11071, b64decode(bfs11070))

  def bfs11072(self, bfs11073=None):
    if (not self.bfs11064):
      return False

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

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

  def bfs11075(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.bfs10162:
      self.encrypted_node_identifier = encrypted_node_identifier



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

    self.file_path = file_path
    self.bfs11076 = bfs11076

  def read(self):
    (bfs11100, key) = self.bfs11102()
    bfs11101 = bfs11103(self.bfs11076)
    bfs11104 = bfs11101.parse(bfs11100, key)
    bfs11104.bfs11062 = self.bfs11062
    return bfs11104

  def bfs11102(self):
    with open(self.file_path, 'r') as bfs11105:
      bfs11107 = bfs11105.readline().rstrip()
      key = bfs11105.readline().rstrip()
      if ((not bfs11107) or (not key)):
        raise InvalidLicenseFile()

      return (bfs11107, key)


  def write(self, bfs11106):
    with open(self.file_path, 'w') as bfs11110:
      bfs11110.write((bfs11106.bfs10166 + '\n'))
      key = bfs11106.code
      if bfs11106.bfs10162:
        key += bfs11106.encrypted_node_identifier

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


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

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


class bfs11103(object):
  def __init__(self, bfs11076=None):
    if (bfs11076 is None):
      bfs11076 = []

    self.bfs11076 = bfs11076

  def parse(self, bfs11112, key):
    code = key[:bfs11061.bfs11060]
    bfs11111 = key[bfs11061.bfs11060:]
    try:
      if (code in self.bfs11076):
        return self.bfs11113(bfs11112, code, bfs11111)
      else:
        return self.bfs11115(bfs11112, code, bfs11111)

    except ValueError:
      return bfs11061(bfs11112, code, encrypted_node_identifier=bfs11111)


  def bfs11113(self, bfs11114, code, encrypted_node_identifier):
    bfs11116 = True
    is_online = True
    bfs11117 = False
    bfs11121 = None
    try:
      bfs11120 = int(code[:1])
    except ValueError:
      bfs11120 = None

    return bfs11061(bfs11114, code, None, encrypted_node_identifier, bfs11116, is_online, bfs11117, bfs11121, bfs11120)

  def bfs11115(self, bfs11122, code, encrypted_node_identifier):
    bfs11124 = bfs11123(code)
    bfs10162 = bfs11124.bfs10162
    is_online = bfs11124.is_online
    bfs11064 = bfs11124.bfs11064
    bfs11063 = bfs11124.bfs11063
    bfs11065 = bfs11124.bfs11065
    return bfs11061(bfs11122, code, None, encrypted_node_identifier, bfs10162, is_online, bfs11064, bfs11063, bfs11065)


class bfs11125:
  bfs11127 = 0
  bfs11126 = 1
  bfs11130 = 2
  bfs11131 = 3
  bfs11132 = 4
  bfs11134 = 5
  bfs11133 = 6

class bfs11123(object):
  bfs11135 = [(bfs11125.bfs11127, 5), (bfs11125.bfs11126, 1), (bfs11125.bfs11130, 1), (bfs11125.bfs11131, 1), (bfs11125.bfs11132, 7), (bfs11125.bfs11134, 4), (bfs11125.bfs11133, 5)]
  def __init__(self, code):
    self.code = code
    bfs11137 = self.bfs11136(self.code)
    self.bfs11065 = self.bfs11140(bfs11137, bfs11125.bfs11127)
    self.is_online = (self.bfs11140(bfs11137, bfs11125.bfs11126) > 0)
    self.bfs10162 = (self.bfs11140(bfs11137, bfs11125.bfs11130) > 0)
    self.bfs11064 = (self.bfs11140(bfs11137, bfs11125.bfs11131) > 0)
    bfs11063 = None
    if self.bfs11064:
      bfs11141 = (2000 + self.bfs11140(bfs11137, bfs11125.bfs11132))
      bfs11142 = self.bfs11140(bfs11137, bfs11125.bfs11134)
      bfs11143 = self.bfs11140(bfs11137, bfs11125.bfs11133)
      bfs11063 = date(bfs11141, bfs11142, bfs11143)

    self.bfs11063 = bfs11063

  def bfs11136(self, text):
    bfs11144 = 6
    assert (len(bfs11057) == (2 ** bfs11144))
    bfs11146 = ''
    for bfs11145 in text:
      bfs11147 = bfs11046(bfs11056(bfs11145, bfs11057), '01')
      while (len(bfs11147) < bfs11144):
        bfs11147 = ('0' + bfs11147)

      bfs11146 += bfs11147

    bfs11150 = (len(text) * bfs11144)
    bfs11151 = int(ceil((log(bfs11150) / log(2))))
    bfs11152 = bfs11146[:bfs11151]
    bfs11154 = bfs11056(bfs11152, '01')
    return bfs11146[bfs11151:(bfs11151 + bfs11154)]

  def bfs11140(self, bfs11153, bfs11155):
    offset = 0
    (bfs11156, bfs11157) = list(zip(*self.bfs11135))
    bfs11161 = bfs11156.index(bfs11155)
    for index in range(0, bfs11161):
      offset += bfs11157[index]

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

    return bfs11056(bfs11153[offset:(offset + bfs11157[bfs11156.index(bfs11155)])], '01')


