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

__all__ = ['REGION', 'IDENTITY_POOL_ID', 'USER_POOL_ID', 'ACCOUNT_ID', 'CLIENT_ID', 'CLIENT_SECRET',
           'COMPULSARY_INPUTS', 'cognito', 'CreateCashier', 'createCashier', 'Auth', 'auth', 'Confirm', 'confirm',
           'GetProfile', 'getProfile', 'UpdateProfile', 'updateProfile', 'SetPassword', 'setPassword', 'unauth',
           'DeleteUser', 'deleteUser', 'refresh']

# Cell
from awsSchema.apigateway import Response, Event
from .cognito import Cognito
from nicHelper.dictUtil import printDict, filterDt
from nicHelper.exception import  errorString
from datetime import datetime
from dataclasses import dataclass
from dataclasses_json import dataclass_json
from typing import Optional
import ujson as json
import os, traceback, base64, pickle

# Cell
REGION = os.environ.get("REGION")
IDENTITY_POOL_ID = os.environ.get('IDENTITY_POOL_ID')
USER_POOL_ID = os.environ.get('USER_POOL_ID')
ACCOUNT_ID = os.environ.get ('ACCOUNT_ID')
CLIENT_ID = os.environ.get ('CLIENT_ID')
CLIENT_SECRET = os.environ.get('CLIENT_SECRET')
COMPULSARY_INPUTS = json.loads(os.environ.get('COMPULSARY_INPUTS','{}'))


# Cell
cognito = Cognito(
  identityPoolId = IDENTITY_POOL_ID ,
  userPoolId = USER_POOL_ID,
  accountId = ACCOUNT_ID,
  clientId = CLIENT_ID,
  clientSecret = CLIENT_SECRET,
  region = REGION
)

# Cell
@dataclass_json
@dataclass
class CreateCashier:
  user: str
  phone: str
  pw: str
  name: str
  cashierCode: str
  email: Optional[str] = None

# Cell
def createCashier(event, *args):
  try:
    createCashierItem:CreateCashier = Event.parseDataClass(CreateCashier, event)
  except Exception as e:
    return Response.returnError(message = f'{e}')
  ## catch error adding user
  try:
    if not (addResult:=cognito.addUser(**createCashierItem.to_dict()))['success']:
      return Response.returnError(message=addResult)
  except:
    return Response.returnError(message=errorString())
  try:
    updateResult = updateProfile(Event.getInput(
      {'user':createCashierItem.user,
       'attributes':{
         'custom:cashierCode': createCashierItem.cashierCode,
         'email': createCashierItem.email or ''
       }}))
  except:
    return Response.returnError(message=f'update cashier code error {errorString()}')
  return Response.returnSuccess(body={**addResult, **createCashierItem.to_dict(), **updateResult})

# Cell
@dataclass_json
@dataclass
class Auth:
  user: str
  password: str

# Cell
def auth(event, *args):
  ####### validate inputs
  authObject: Auth = Event.parseDataClass(Auth, event)
  print(f'user is {authObject.user} pw is {authObject.password}')
  ####### main function
  try:
    success, token = cognito.login(user = authObject.user, pw = authObject.password)
    if not success: return Response.returnError(message=token)
  except:
    return Response.returnError(message={'error': traceback.format_exc()})
  ##### clean up non-json parsable string ####
  token = filterDt(token)
  return Response.returnSuccess(body=token)

# Cell
@dataclass_json
@dataclass
class Confirm:
  user: str
  code: str

def confirm(event, *args):
  try: confirmItem:Confirm = Event.parseDataClass(Confirm, event)
  except Exception as e: return Response.returnError(f'{e}')

  if not (result := cognito.confirm(**confirmItem.to_dict()))['success']:
    resultString = base64.b64encode(pickle.dumps(result)).decode()
    return Response.returnError(message = {'pickledb64string': resultString, 'error': 'confirmation code error'})
  return Response.returnSuccess(body = result)

# Cell
@dataclass_json
@dataclass
class GetProfile:
  user:str

def getProfile(event, *args):
  ### validate input
  try: inputItem = Event.parseDataClass(GetProfile, event)
  except Exception as e: return Response.returnError(message = f'{e}')
  #### call sdk
  if not (result:= cognito.getAttribute(inputItem.user)):
    return Response.returnError(message = f'{result}')
  return Response.returnSuccess(result)

# Cell
@dataclass_json
@dataclass
class UpdateProfile:
  user: str
  attributes: dict

def updateProfile(event, *args):
  f'''add attributes to the user
    event schema
    body: JSON String
      {UpdateProfile.__doc__}
  '''
  ### validate input
  try: inputItem = Event.parseDataClass(UpdateProfile, event)
  except Exception as e: return Response.returnError(message = f'{e}')
  ### call sdk
  success, result = cognito.updateAttribute(inputItem.user, inputItem.attributes)
  if not success:
    return Response.returnError(message = f'{result}')
  return Response.returnSuccess(body=result)

# Cell
@dataclass_json
@dataclass
class SetPassword:
  user: str
  pw: str

def setPassword(event, *args):
  ### validate input
  try: inputItem = Event.parseDataClass(SetPassword, event)
  except Exception as e: return Response.returnError(message = f'{e}')
  ### call sdk
  success, result = cognito.setNewPassword(inputItem.user, inputItem.pw)
  if not success:
    return Response.returnError(message=f'{result}')
  return Response.returnSuccess(result)

# Cell
def unauth(event, *args):
  unauthCreden = cognito.unAuthCreden()
  cleanedCreden = {k:(v.timestamp() if type(v)==datetime else v) for k,v in unauthCreden.items()}
  return Response.returnSuccess(cleanedCreden)

# Cell
@dataclass_json
@dataclass
class DeleteUser:
  user: str

# Cell
def deleteUser(event,*args):
  body = Event.parseBody(event)
  try: deleteUserObject: DeleteUser = DeleteUser.from_dict(body)
  except: return Response.returnError(message=f'input should have the schema{DeleteUser.__doc__}')
  try: result = cognito.deleteUser(deleteUserObject.user)
  except: return Response.returnError(message=f'{errorString()}')
  return Response.returnSuccess(result)



# Cell
def refresh(event, *args):
  return Response.returnSuccess({})