// Copyright 2017 The Cobalt Authors. All Rights Reserved.
//
// 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 "starboard/android/shared/file_internal.h"

#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>
#include <android/log.h>
#include <jni.h>
#include <string>

#include "starboard/android/shared/jni_env_ext.h"
#include "starboard/android/shared/jni_utils.h"
#include "starboard/common/log.h"
#include "starboard/common/string.h"
#include "starboard/memory.h"

namespace starboard {
namespace android {
namespace shared {

const char* g_app_assets_dir = "/cobalt/assets";
const char* g_app_files_dir = NULL;
const char* g_app_cache_dir = NULL;
const char* g_app_lib_dir = NULL;

namespace {
jobject g_java_asset_manager;
AAssetManager* g_asset_manager;

// Copies the characters from a jstring and returns a newly allocated buffer
// with the result.
const char* DuplicateJavaString(JniEnvExt* env, jstring j_string) {
  SB_DCHECK(j_string);
  std::string utf_str = env->GetStringStandardUTFOrAbort(j_string);
  const char* result = strdup(utf_str.c_str());
  return result;
}

}  // namespace

void SbFileAndroidInitialize() {
  JniEnvExt* env = JniEnvExt::Get();

  SB_DCHECK(g_java_asset_manager == NULL);
  SB_DCHECK(g_asset_manager == NULL);
  ScopedLocalJavaRef<jstring> j_app(env->CallStarboardObjectMethodOrAbort(
      "getApplicationContext", "()Landroid/content/Context;"));
  g_java_asset_manager =
      env->ConvertLocalRefToGlobalRef(env->CallObjectMethodOrAbort(
          j_app.Get(), "getAssets", "()Landroid/content/res/AssetManager;"));
  g_asset_manager = AAssetManager_fromJava(env, g_java_asset_manager);

  SB_DCHECK(g_app_files_dir == NULL);
  ScopedLocalJavaRef<jstring> j_string(env->CallStarboardObjectMethodOrAbort(
      "getFilesAbsolutePath", "()Ljava/lang/String;"));
  g_app_files_dir = DuplicateJavaString(env, j_string.Get());
  SB_DLOG(INFO) << "Files dir: " << g_app_files_dir;

  SB_DCHECK(g_app_cache_dir == NULL);
  j_string.Reset(env->CallStarboardObjectMethodOrAbort("getCacheAbsolutePath",
                                                       "()Ljava/lang/String;"));
  g_app_cache_dir = DuplicateJavaString(env, j_string.Get());
  SB_DLOG(INFO) << "Cache dir: " << g_app_cache_dir;

  SB_DCHECK(g_app_lib_dir == NULL);
  ScopedLocalJavaRef<jobject> j_app_info(
      env->CallObjectMethodOrAbort(j_app.Get(), "getApplicationInfo",
                                   "()Landroid/content/pm/ApplicationInfo;"));
  j_string.Reset(
      env->GetStringFieldOrAbort(j_app_info.Get(), "nativeLibraryDir"));
  g_app_lib_dir = DuplicateJavaString(env, j_string.Get());
  SB_DLOG(INFO) << "Lib dir: " << g_app_lib_dir;
}

void SbFileAndroidTeardown() {
  JniEnvExt* env = JniEnvExt::Get();

  if (g_java_asset_manager) {
    env->DeleteGlobalRef(g_java_asset_manager);
    g_java_asset_manager = NULL;
    g_asset_manager = NULL;
  }

  if (g_app_files_dir) {
    free(const_cast<char*>(g_app_files_dir));
    g_app_files_dir = NULL;
  }

  if (g_app_cache_dir) {
    free(const_cast<char*>(g_app_cache_dir));
    g_app_cache_dir = NULL;
  }
}

bool IsAndroidAssetPath(const char* path) {
  size_t prefix_len = strlen(g_app_assets_dir);
  return path != NULL && strncmp(g_app_assets_dir, path, prefix_len) == 0 &&
         (path[prefix_len] == '/' || path[prefix_len] == '\0');
}

AAsset* OpenAndroidAsset(const char* path) {
  if (!IsAndroidAssetPath(path) || g_asset_manager == NULL) {
    return NULL;
  }
  const char* asset_path = path + strlen(g_app_assets_dir) + 1;
  return AAssetManager_open(g_asset_manager, asset_path, AASSET_MODE_RANDOM);
}

AAssetDir* OpenAndroidAssetDir(const char* path) {
  // Note that the asset directory will not be found if |path| points to a
  // specific file instead of a directory. |path| should also not end with '/'.
  if (!IsAndroidAssetPath(path) || g_asset_manager == NULL) {
    return NULL;
  }
  const char* asset_path = path + strlen(g_app_assets_dir);
  if (*asset_path == '/') {
    asset_path++;
  }
  AAssetDir* asset_directory =
      AAssetManager_openDir(g_asset_manager, asset_path);

  // AAssetManager_openDir() always returns a pointer to an initialized object,
  // even if the given directory does not exist. To determine if the directory
  // actually exists, AAssetDir_getNextFileName() is called to check for any
  // files in the given directory. However, when iterating the contents of a
  // directory, the NDK Asset Manager does not allow subdirectories to be seen.
  // So this is not a 100% accurate way to determine if a directory actually
  // exists and false negatives will be given for directories that contain
  // subdirectories but no files in their immediate directory.
  const char* file = AAssetDir_getNextFileName(asset_directory);
  if (file == NULL) {
    AAssetDir_close(asset_directory);
    return NULL;
  } else {
    AAssetDir_rewind(asset_directory);
    return asset_directory;
  }
}

}  // namespace shared
}  // namespace android
}  // namespace starboard
