# AUTOGENERATED! DO NOT EDIT! File to edit: S3.ipynb (unless otherwise specified).

__all__ = ['DBHASHLOCATION', 'DBCACHELOCATION', 'DATABASE_TABLE_NAME', 'INVENTORY_BUCKET_NAME', 'INPUT_BUCKET_NAME',
           'REGION', 'ACCESS_KEY_ID', 'SECRET_ACCESS_KEY', 'LINEKEY', 'ALLDATAKEY', 'DEFAULTKEYS', 'S3Cache',
           'loadFromCache', 'saveRemoteCache', 'resetS3Cache']

# Cell
from s3bz.s3bz import S3
from nicHelper.wrappers import add_method, add_class_method, add_static_method
from nicHelper.dictUtil import stripDict, printDict, hashDict, saveStringToFile, loadStringFromFile, saveDictToFile, loadDictFromFile
from nicHelper.exception import errorString
import nicHelper.pdUtils as pdUtils
from dict_hash import dict_hash, sha256
from base64 import b64encode, b64decode
from pandas.util import hash_pandas_object
from hashlib import sha1
import pandas as pd
import os, logging, zlib

# Cell
import os
DBHASHLOCATION = '/mnt/efs/database.hash'
DBCACHELOCATION = '/mnt/efs/database.cache'
DATABASE_TABLE_NAME = os.environ.get('DATABASE_TABLE_NAME')
INVENTORY_BUCKET_NAME = os.environ.get('INVENTORY_BUCKET_NAME')
INPUT_BUCKET_NAME = os.environ.get('INPUT_BUCKET_NAME')
REGION = os.environ.get('REGION') or 'ap-southeast-1'
ACCESS_KEY_ID = os.environ.get('USER') or None
SECRET_ACCESS_KEY = os.environ.get('PW') or None
LINEKEY= os.environ.get('LINEKEY')
ALLDATAKEY = 'allData'
DEFAULTKEYS = ['cprcode', 'iprcode', 'oprcode', 'ordertype', 'pr_abb', 'pr_active', 'pr_cgcode', 'pr_code', 'pr_dpcode', 'pr_engname', 'pr_ggcode', 'pr_market', 'pr_name', 'pr_puqty', 'pr_sa_method', 'pr_sucode1', 'pr_suref3', 'prtype', 'psqty', 'pstype']

try:
  DAX_ENDPOINT = os.environ['DAX_ENDPOINT']
  print(DAX_ENDPOINT)
except KeyError as e:
  print(f'dax endpoint missing {e}')


# Cell
class S3Cache:
  pass

# Cell
@add_class_method(S3Cache)
def loadFromCache(cls, key=ALLDATAKEY, localCache=DBCACHELOCATION,
                  localHash=DBHASHLOCATION, bucket=INVENTORY_BUCKET_NAME):
  ## check for local object and its hash
  if os.path.exists(localCache) and os.path.exists(localHash):
    try:
      localHash = pdUtils.loadLocalHash(path=localHash)
      logging.debug(f'localHash is {localHash}')
      remoteHash = pdUtils.loadRemoteHash(key=key, bucket=bucket)
      logging.debug(f'remoteHash is {remoteHash}')

      if localHash == remoteHash:
        print('data is still in sync, using local cache')
        db = pdUtils.loadLocalCache(path=localCache)
        return db
      else:
        print('remote hash is not the same, load remote cache')
    except Exception as e: print(f'local loading error{e}, loading remote hash')
  ### load from remote cache
  try:
    db = pdUtils.loadRemoteCache(key=key, bucket=bucket)
    pdUtils.saveLocalCache(db, path=localCache)
    pdUtils.saveLocalHash(db, path = localHash)
  except Exception as e:
    print(f'locding remtoe failed {e} returning blank df')
    db = pd.DataFrame(columns = DEFAULTKEYS)
  ### save to local cache
  return db

# Cell

@add_class_method(S3Cache)
def saveRemoteCache(cls ,db:pd.DataFrame, key= ALLDATAKEY,
                   bucket = INVENTORY_BUCKET_NAME, localCachePath=DBCACHELOCATION,
                   localHashPath=DBHASHLOCATION):
  if db.empty:
    db = pd.DataFrame([DUMMYDATA])
  db.columns = db.columns.astype(str)
  db = db.reset_index(drop=True)

#   print(db)
  pdUtils.saveRemoteCache(data=db, key= key,
                          bucket=bucket, localCachePath=localCachePath,
                          localHashPath=localHashPath)
  jsonDb = db.to_json(orient='split')
  zlibArc = zlib.compress(jsonDb.encode())
  tmpPath = '/tmp/zlibJsonCache.zl'
  with open(tmpPath, 'wb') as f:
    f.write(zlibArc)
  S3.saveFile(key=f'{key}-json.zl',path=tmpPath,bucket=bucket)



# Cell
@add_class_method(S3Cache)
def resetS3Cache(cls, bucketName= INVENTORY_BUCKET_NAME, key = 'allData', limit=10000, **kwargs):
  ''' upload changes to s3'''
  ###### get all data
  items:List[cls] = cls.scanDb(limit=limit)
  print('db is scanned')
  db:pd.DataFrame = cls.toDf(items)
  print(f'{db.shape} changes to update')
  cls.saveRemoteCache(db)
  return True