class CalendarBlocker:
    def __init__(self, logger, correlation_id):
        self.logger = logger
        self.correlation_id = correlation_id
        self.calendars_table = "Calendars"
        self.blocks_table = "CalendarBlocks"
        self.ddb_client = Dynamodb(stack_name=STACK_NAME)
        self.acuity_client = AcuityClient()
        self.sns_client = SnsClient()

    def notify_sns_topic(self, message, subject):
        topic_arn = utils.get_secret(
            "sns-topics")["interview-notifications-arn"]
        self.sns_client.publish(
            message=message,
            topic_arn=topic_arn,
            Subject=subject,
        )

    def get_target_calendar_ids(self):
        calendars = self.ddb_client.scan(
            self.calendars_table,
            "block_monday_morning",
            [True],
        )
        return [(x["id"], x["label"]) for x in calendars]

    def block_upcoming_weekend(self, calendar_id):
        next_monday_date = next_weekday(0)
        block_end = datetime.datetime.combine(next_monday_date,
                                              datetime.time(hour=12, minute=0))
        saturday_before_next_monday = next_monday_date - datetime.timedelta(
            days=2)
        block_start = datetime.datetime.combine(
            saturday_before_next_monday, datetime.time(hour=0, minute=0))
        return self.acuity_client.post_block(calendar_id, block_start,
                                             block_end)

    def create_blocks(self):
        calendars = self.get_target_calendar_ids()
        self.logger.debug("Calendars to block", extra={"calendars": calendars})
        created_blocks_ids = list()
        affected_calendar_names = list()
        for i, name in calendars:
            try:
                block_dict = self.block_upcoming_weekend(i)
                created_blocks_ids.append(block_dict["id"])
                affected_calendar_names.append(name)
                response = self.ddb_client.put_item(
                    self.blocks_table,
                    block_dict["id"],
                    item_type="calendar-block",
                    item_details=block_dict,
                    item={
                        "status": "new",
                        "error_message": None,
                    },
                    correlation_id=self.correlation_id,
                )
                assert (
                    response["ResponseMetadata"]["HTTPStatusCode"] ==
                    HTTPStatus.OK
                ), f"Call to Dynamodb client put_item method failed with response: {response}. "
            except Exception as err:
                self.logger.error(
                    f"{repr(err)} {len(created_blocks_ids)} blocks were created before this error occurred. "
                    f"Created blocks ids: {created_blocks_ids}")
                raise

        return created_blocks_ids, affected_calendar_names

    def mark_failed_block_deletion(self, item_key, exception):
        error_message = f"This error happened when trying to delete Acuity calendar block {item_key}: {repr(exception)}"
        self.logger.error(error_message)
        self.ddb_client.update_item(
            self.blocks_table,
            item_key,
            name_value_pairs={
                "status": "error",
                "error_message": error_message
            },
        )

    def delete_blocks(self):
        blocks = self.ddb_client.scan(
            self.blocks_table,
            filter_attr_name="status",
            filter_attr_values=["new"],
        )
        deleted_blocks_ids = list()
        affected_calendar_names = list()
        for b in blocks:
            item_key = b.get("id")
            try:
                delete_response = self.acuity_client.delete_block(item_key)
                assert delete_response == HTTPStatus.NO_CONTENT, (
                    f"Call to Acuity client delete_block method failed with response: {delete_response}. "
                    f"{len(deleted_blocks_ids)} blocks were deleted before this error occurred. Deleted blocks ids: {deleted_blocks_ids}"
                )
                deleted_blocks_ids.append(item_key)
                affected_calendar_names.append(
                    self.acuity_client.get_calendar_by_id(
                        b["details"]["calendarID"])["name"])
                response = self.ddb_client.delete_item(
                    self.blocks_table,
                    item_key,
                    correlation_id=self.correlation_id)
                assert (
                    response["ResponseMetadata"]["HTTPStatusCode"] ==
                    HTTPStatus.OK
                ), (f"Call to Dynamodb client delete_item method failed with response: {response}. "
                    f"{len(deleted_blocks_ids)} blocks were deleted before this error occurred. Deleted blocks ids: {deleted_blocks_ids}"
                    )
            except Exception as err:
                self.mark_failed_block_deletion(item_key, err)
                continue

        return deleted_blocks_ids, affected_calendar_names
def main(output_filename='test_data_draft.py', items_n=100, depth=None):
    ddb_client = Dynamodb(stack_name=const.STACK_NAME)
    items = ddb_client.scan(table_name=const.AUTH0_EVENTS_TABLE_NAME, )
    selected_items = anonymise_data(random.sample(items, items_n))
    with open(output_filename, 'w') as f:
        pprint(selected_items, stream=f, depth=depth)