// Copyright 2017 The Bazel 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.

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <windows.h>

#include <memory>
#include <sstream>
#include <string>

#include "src/main/native/jni.h"
#include "src/main/native/windows/file.h"
#include "src/main/native/windows/jni-util.h"
#include "src/main/native/windows/util.h"

static bool CanReportError(JNIEnv* env, jobjectArray error_msg_holder) {
  return error_msg_holder != nullptr &&
         env->GetArrayLength(error_msg_holder) > 0;
}

static void ReportLastError(const std::wstring& error_str, JNIEnv* env,
                            jobjectArray error_msg_holder) {
  jstring error_msg = env->NewString(
      reinterpret_cast<const jchar*>(error_str.c_str()), error_str.size());
  env->SetObjectArrayElement(error_msg_holder, 0, error_msg);
}

extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_windows_WindowsFileOperations_nativeIsSymlinkOrJunction(
    JNIEnv* env, jclass clazz, jstring path, jbooleanArray result_holder,
    jobjectArray error_msg_holder) {
  std::wstring wpath(bazel::windows::GetJavaWstring(env, path));
  std::wstring error;
  bool is_sym = false;
  int result =
      bazel::windows::IsSymlinkOrJunction(wpath.c_str(), &is_sym, &error);
  if (result == bazel::windows::IsSymlinkOrJunctionResult::kSuccess) {
    jboolean is_sym_jbool = is_sym ? JNI_TRUE : JNI_FALSE;
    env->SetBooleanArrayRegion(result_holder, 0, 1, &is_sym_jbool);
  } else {
    if (!error.empty() && CanReportError(env, error_msg_holder)) {
      ReportLastError(
          bazel::windows::MakeErrorMessage(WSTR(__FILE__), __LINE__,
                                           L"nativeIsJunction", wpath, error),
          env, error_msg_holder);
    }
  }
  return static_cast<jint>(result);
}

extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_windows_WindowsFileOperations_nativeGetChangeTime(
    JNIEnv* env, jclass clazz, jstring path, jboolean follow_reparse_points,
    jlongArray result_holder, jobjectArray error_msg_holder) {
  std::wstring wpath(bazel::windows::GetJavaWstring(env, path));
  std::wstring error;
  jlong ctime = 0;
  int result =
      bazel::windows::GetChangeTime(wpath.c_str(), follow_reparse_points,
                                    reinterpret_cast<int64_t*>(&ctime), &error);
  if (result == bazel::windows::GetChangeTimeResult::kSuccess) {
    env->SetLongArrayRegion(result_holder, 0, 1, &ctime);
  } else {
    if (!error.empty() && CanReportError(env, error_msg_holder)) {
      ReportLastError(
          bazel::windows::MakeErrorMessage(
              WSTR(__FILE__), __LINE__, L"nativeGetChangeTime", wpath, error),
          env, error_msg_holder);
    }
  }
  return static_cast<jint>(result);
}

extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_devtools_build_lib_windows_WindowsFileOperations_nativeGetLongPath(
    JNIEnv* env, jclass clazz, jstring path, jobjectArray result_holder,
    jobjectArray error_msg_holder) {
  std::unique_ptr<WCHAR[]> result;
  std::wstring wpath(bazel::windows::GetJavaWstring(env, path));
  std::wstring error(bazel::windows::GetLongPath(wpath.c_str(), &result));
  if (!error.empty()) {
    if (CanReportError(env, error_msg_holder)) {
      ReportLastError(
          bazel::windows::MakeErrorMessage(WSTR(__FILE__), __LINE__,
                                           L"nativeGetLongPath", wpath, error),
          env, error_msg_holder);
    }
    return JNI_FALSE;
  }
  env->SetObjectArrayElement(
      result_holder, 0,
      env->NewString(reinterpret_cast<const jchar*>(result.get()),
                     wcslen(result.get())));
  return JNI_TRUE;
}

extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_windows_WindowsFileOperations_nativeCreateJunction(
    JNIEnv* env, jclass clazz, jstring name, jstring target,
    jobjectArray error_msg_holder) {
  std::wstring wname(bazel::windows::GetJavaWstring(env, name));
  std::wstring wtarget(bazel::windows::GetJavaWstring(env, target));
  std::wstring error;
  int result = bazel::windows::CreateJunction(wname, wtarget, &error);
  if (result != bazel::windows::CreateJunctionResult::kSuccess &&
      !error.empty() && CanReportError(env, error_msg_holder)) {
    ReportLastError(bazel::windows::MakeErrorMessage(
                        WSTR(__FILE__), __LINE__, L"nativeCreateJunction",
                        wname + L", " + wtarget, error),
                    env, error_msg_holder);
  }
  return static_cast<jint>(result);
}

extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_windows_WindowsFileOperations_nativeCreateSymlink(
    JNIEnv* env, jclass clazz, jstring name, jstring target,
    jobjectArray error_msg_holder) {
  std::wstring wname(bazel::windows::GetJavaWstring(env, name));
  std::wstring wtarget(bazel::windows::GetJavaWstring(env, target));
  std::wstring error;
  int result = bazel::windows::CreateSymlink(wname, wtarget, &error);
  if (result != bazel::windows::CreateSymlinkResult::kSuccess &&
      !error.empty() && CanReportError(env, error_msg_holder)) {
    ReportLastError(bazel::windows::MakeErrorMessage(
                        WSTR(__FILE__), __LINE__, L"nativeCreateSymlink",
                        wname + L", " + wtarget, error),
                    env, error_msg_holder);
  }
  return static_cast<jint>(result);
}

extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_windows_WindowsFileOperations_nativeReadSymlinkOrJunction(
    JNIEnv* env, jclass clazz, jstring name, jobjectArray target_holder,
    jobjectArray error_msg_holder) {
  std::wstring wname(bazel::windows::GetJavaWstring(env, name));
  std::wstring target, error;
  int result = bazel::windows::ReadSymlinkOrJunction(wname, &target, &error);
  if (result == bazel::windows::ReadSymlinkOrJunctionResult::kSuccess) {
    env->SetObjectArrayElement(
        target_holder, 0,
        env->NewString(reinterpret_cast<const jchar*>(target.c_str()),
                       target.size()));
  } else {
    if (!error.empty() && CanReportError(env, error_msg_holder)) {
      ReportLastError(bazel::windows::MakeErrorMessage(
                          WSTR(__FILE__), __LINE__,
                          L"nativeReadSymlinkOrJunction", wname, error),
                      env, error_msg_holder);
    }
  }
  return static_cast<jint>(result);
}

extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_windows_WindowsFileOperations_nativeDeletePath(
    JNIEnv* env, jclass clazz, jstring path, jobjectArray error_msg_holder) {
  std::wstring wpath(bazel::windows::GetJavaWstring(env, path));
  std::wstring error;
  int result = bazel::windows::DeletePath(wpath, &error);
  if (result != bazel::windows::DeletePathResult::kSuccess && !error.empty() &&
      CanReportError(env, error_msg_holder)) {
    ReportLastError(
        bazel::windows::MakeErrorMessage(WSTR(__FILE__), __LINE__,
                                         L"nativeDeletePath", wpath, error),
        env, error_msg_holder);
  }
  return result;
}
