/**
 * 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 <IMediaExtractor.h>
#include <dlfcn.h>
#include "../includes/common.h"
#include "../includes/memutils.h"

#if _32_BIT
#define LIBNAME "/system/lib/extractors/libmidiextractor.so"
#define LIBNAME_APEX "/apex/com.android.media/lib/extractors/libmidiextractor.so"
#elif _64_BIT
#define LIBNAME "/system/lib64/extractors/libmidiextractor.so"
#define LIBNAME_APEX "/apex/com.android.media/lib64/extractors/libmidiextractor.so"
#endif

char enable_selective_overload = ENABLE_NONE;

using namespace android;

bool isTestInProgress = false;

struct sigaction new_action, old_action;

int fdData, fdInfo;

void *libHandle = nullptr;

void sigsegv_handler(int signum, siginfo_t *info, void *context) {
    if (isTestInProgress && info->si_signo == SIGSEGV) {
        (*old_action.sa_sigaction)(signum, info, context);
        return;
    }
    _exit(EXIT_FAILURE);
}

class XMFDataSource : public DataSource {
   public:
    int mFdData;
    int mFdInfo;
    XMFDataSource(int fdData, int fdInfo) {
        mFdData = fdData;
        mFdInfo = fdInfo;
  }

  ~XMFDataSource() = default;

  virtual ssize_t readAt(off64_t offset __attribute__((unused)), void *data, size_t size) {
      uint32_t infoOffset, infoSize;
      read(mFdInfo, &infoSize, sizeof(int32_t));
      read(mFdInfo, &infoOffset, sizeof(int32_t));
      lseek(mFdData, infoOffset, SEEK_SET);
      read(mFdData, data, infoSize);
      return size;
  }

  virtual status_t getSize(off64_t *size) {
    *size = 0x10000;
    return 0;
  }
  virtual status_t initCheck() const { return 0; }
};

void close_resources() {
    if (fdData >= 0) {
        ::close(fdData);
    }
    if (fdInfo >= 0) {
        ::close(fdInfo);
    }
    if (libHandle) {
        dlclose(libHandle);
    }
}

int main(int argc, char **argv) {
    atexit(close_resources);

    sigemptyset(&new_action.sa_mask);
    new_action.sa_flags = SA_SIGINFO;
    new_action.sa_sigaction = sigsegv_handler;
    sigaction(SIGSEGV, &new_action, &old_action);

    FAIL_CHECK(argc == 3);
    libHandle = dlopen(LIBNAME, RTLD_NOW | RTLD_LOCAL);
    if (!libHandle) {
        libHandle = dlopen(LIBNAME_APEX, RTLD_NOW | RTLD_LOCAL);
        FAIL_CHECK(libHandle);
  }

  GetExtractorDef getDef = (GetExtractorDef)dlsym(libHandle, "GETEXTRACTORDEF");
  FAIL_CHECK(getDef);

  fdData = open(argv[1], O_RDONLY);
  FAIL_CHECK(fdData >= 0);

  fdInfo = open(argv[2], O_RDONLY);
  FAIL_CHECK(fdInfo >= 0);

  sp<DataSource> dataSource = (sp<DataSource>)new XMFDataSource(fdData, fdInfo);
  FAIL_CHECK(dataSource);

  enable_selective_overload = ENABLE_ALL;
  isTestInProgress = true;

  void *meta = nullptr;
  FreeMetaFunc freeMeta = nullptr;
  float confidence = 0.0f;
  if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V1) {
    getDef().u.v2.sniff(dataSource->wrap(), &confidence, &meta, &freeMeta);
  } else if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V2) {
    getDef().u.v3.sniff(dataSource->wrap(), &confidence, &meta, &freeMeta);
  }

  isTestInProgress = false;
  enable_selective_overload = ENABLE_FREE_CHECK | ENABLE_REALLOC_CHECK;
  return EXIT_SUCCESS;
}
