/*
 * 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 "chpp/clients/loopback.h"

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>

#include "chpp/app.h"
#include "chpp/clients.h"
#include "chpp/memory.h"
#include "chpp/platform/log.h"
#include "chpp/transport.h"

/************************************************
 *  Prototypes
 ***********************************************/

/************************************************
 *  Private Definitions
 ***********************************************/

/**
 * Structure to maintain state for the loopback client and its Request/Response
 * (RR) functionality.
 */
struct ChppLoopbackClientState {
  struct ChppClientState client;                    // Loopback client state
  struct ChppRequestResponseState runLoopbackTest;  // Loopback test state

  struct ChppLoopbackTestResult testResult;  // Last test result
  uint8_t *loopbackRequest;                  // Pointer to saved loopback data
};

// Note: This global definition of gLoopbackClientContext supports only one
// instance of the CHPP loopback client at a time.
struct ChppLoopbackClientState gLoopbackClientContext = {};

/************************************************
 *  Public Functions
 ***********************************************/

void chppLoopbackClientInit(struct ChppAppState *context) {
  gLoopbackClientContext.client.appContext = context;
  chppClientInit(&gLoopbackClientContext.client, CHPP_HANDLE_LOOPBACK);
  gLoopbackClientContext.testResult.error = CHPP_APP_ERROR_NONE;
}

void chppLoopbackClientDeinit() {
  chppClientDeinit(&gLoopbackClientContext.client);
}

bool chppDispatchLoopbackServiceResponse(struct ChppAppState *context,
                                         const uint8_t *buf, size_t len) {
  UNUSED_VAR(context);
  CHPP_ASSERT(len < CHPP_LOOPBACK_HEADER_LEN);

  chppClientTimestampResponse(&gLoopbackClientContext.runLoopbackTest,
                              (struct ChppAppHeader *)buf);

  gLoopbackClientContext.testResult.error = CHPP_APP_ERROR_NONE;
  gLoopbackClientContext.testResult.responseLen = len;
  gLoopbackClientContext.testResult.firstError = len;
  gLoopbackClientContext.testResult.byteErrors = 0;
  gLoopbackClientContext.testResult.rtt =
      gLoopbackClientContext.runLoopbackTest.responseTime -
      gLoopbackClientContext.runLoopbackTest.requestTime;

  if (gLoopbackClientContext.testResult.requestLen !=
      gLoopbackClientContext.testResult.responseLen) {
    gLoopbackClientContext.testResult.error = CHPP_APP_ERROR_INVALID_LENGTH;
    gLoopbackClientContext.testResult.firstError =
        MIN(gLoopbackClientContext.testResult.requestLen,
            gLoopbackClientContext.testResult.responseLen);
  }

  for (size_t loc = CHPP_LOOPBACK_HEADER_LEN;
       loc < MIN(gLoopbackClientContext.testResult.requestLen,
                 gLoopbackClientContext.testResult.responseLen);
       loc++) {
    if (gLoopbackClientContext.loopbackRequest[loc] != buf[loc]) {
      gLoopbackClientContext.testResult.error = CHPP_APP_ERROR_UNSPECIFIED;
      gLoopbackClientContext.testResult.firstError =
          MIN(gLoopbackClientContext.testResult.firstError, loc);
      gLoopbackClientContext.testResult.byteErrors++;
    }
  }

  return true;
}

struct ChppLoopbackTestResult chppRunLoopbackTest(struct ChppAppState *context,
                                                  const uint8_t *buf,
                                                  size_t len) {
  UNUSED_VAR(context);

  if (gLoopbackClientContext.testResult.error == CHPP_APP_ERROR_BLOCKED) {
    CHPP_LOGE("Loopback test cannot be run while another is in progress");
    CHPP_DEBUG_ASSERT(false);

  } else {
    gLoopbackClientContext.testResult.error = CHPP_APP_ERROR_BLOCKED;
    gLoopbackClientContext.testResult.requestLen =
        len + CHPP_LOOPBACK_HEADER_LEN;
    gLoopbackClientContext.testResult.responseLen = 0;
    gLoopbackClientContext.testResult.firstError = 0;
    gLoopbackClientContext.testResult.byteErrors = 0;
    gLoopbackClientContext.testResult.rtt = 0;

    if (len == 0) {  // Length too short for a loopback test
      gLoopbackClientContext.testResult.error = CHPP_APP_ERROR_INVALID_LENGTH;

    } else {
      gLoopbackClientContext.loopbackRequest =
          (uint8_t *)chppAllocClientRequest(
              &gLoopbackClientContext.client,
              gLoopbackClientContext.testResult.requestLen);

      if (gLoopbackClientContext.loopbackRequest == NULL) {
        // OOM
        gLoopbackClientContext.testResult.requestLen = 0;
        gLoopbackClientContext.testResult.error = CHPP_APP_ERROR_OOM;
        CHPP_LOG_OOM();

      } else {
        memcpy(
            &gLoopbackClientContext.loopbackRequest[CHPP_LOOPBACK_HEADER_LEN],
            buf, len);

        if (!chppSendTimestampedRequestAndWait(
                &gLoopbackClientContext.client,
                &gLoopbackClientContext.runLoopbackTest,
                gLoopbackClientContext.loopbackRequest,
                gLoopbackClientContext.testResult.requestLen)) {
          gLoopbackClientContext.testResult.error = CHPP_APP_ERROR_UNSPECIFIED;
        }  // else {gLoopbackClientContext.testResult is now populated}
      }
    }
  }

  return gLoopbackClientContext.testResult;
}
