/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 "android/bridge/platform/android_side.h"

#include "android/base/string/string_utils.h"
#include "android/utils/ipc_string_result.h"
#include "android/utils/cache_utils.h"
#include "android/utils/params_utils.h"
#include "android/wrap/hash_set.h"
#include "android/wrap/log_utils.h"
#include "android/wrap/wml_bridge.h"
#include "android/wrap/wx_js_object.h"
#include "android/wrap/wx_map.h"
#include "base/android/jni/android_jni.h"
#include "base/android/jni/jbytearray_ref.h"
#include "base/android/jni_type.h"
#include "base/log_defines.h"
#include "core/layout/layout.h"
#include "core/layout/measure_func_adapter.h"
#include "core/manager/weex_core_manager.h"
#include "third_party/IPC/IPCResult.h"

namespace WeexCore {

AndroidSide::AndroidSide()
    : wml_bridge_(WMLBridge::Instance()), wx_bridge_(WXBridge::Instance()) {}

AndroidSide::~AndroidSide() {}

WXCoreSize AndroidSide::InvokeMeasureFunction(const char *page_id,
                                              long render_ptr, float width,
                                              int width_measure_mode,
                                              float height,
                                              int height_measure_mode) {
  return WeexCoreManager::Instance()->measure_function_adapter()->Measure(
      page_id, render_ptr, width, static_cast<MeasureMode>(width_measure_mode),
      height, static_cast<MeasureMode>(height_measure_mode));
}
void AndroidSide::InvokeLayoutBefore(const char *page_id, long render_ptr) {
  WeexCoreManager::Instance()->measure_function_adapter()->LayoutBefore(
      page_id, render_ptr);
}

void AndroidSide::InvokeLayoutPlatform(const char* page_id, long render_ptr) {
  // do nothing
}

void AndroidSide::TriggerVSync(const char* page_id) {
  // do nothing
}

void AndroidSide::InvokeLayoutAfter(const char *page_id, long render_ptr,
                                    float width, float height) {
  WeexCoreManager::Instance()->measure_function_adapter()->LayoutAfter(
      page_id, render_ptr, width, height);
}

void AndroidSide::SetJSVersion(const char *version) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return;

  wx_bridge_->SetJSFrmVersion(env, version);
}

void AndroidSide::ReportException(const char *page_id, const char *func,
                                  const char *exception_string) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return;

  wx_bridge_->ReportException(env, page_id, func, exception_string);
}

void AndroidSide::ReportServerCrash(const char *instance_id) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return;

  std::string crash_file;
  crash_file.assign("/crash_dump.log");
  wx_bridge_->ReportServerCrash(env, instance_id, crash_file.c_str());
}

void AndroidSide::ReportNativeInitStatus(const char *status_code,
                                         const char *error_msg) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return;

  wx_bridge_->ReportNativeInitStatus(env, status_code, error_msg);
}

int AndroidSide::CallNative(const char *page_id, const char *task,
                            const char *callback) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return -1;

  int flag = wx_bridge_->CallNative(env, page_id, task, callback);
  if (flag == -1) {
    LOGE("instance destroy JFM must stop callNative");
  }
  return flag;
}
int AndroidSide::AddChildToRichtext(const char *pageId, const char *nodeType, const char *ref, const char *parentRef,
                                    const char *richtextRef, std::map<std::string, std::string> *styles,
                                    std::map<std::string, std::string> *attributes) {
    JNIEnv *env = base::android::AttachCurrentThread();
    if (env == nullptr)
        return -1;
    int flag = wx_bridge_->AddChildToRichtext(env, pageId, nodeType, ref, parentRef, richtextRef, styles ,attributes);
    if (flag == -1) {
        LOGE("instance destroy JFM must stop AddChildToRichtext");
    }
    return flag;
}
int AndroidSide::RemoveChildFromRichtext(const char *pageId, const char *ref, const char *parent_ref,
                                         const char *richtext_ref) {
    JNIEnv *env = base::android::AttachCurrentThread();
    if (env == nullptr)
        return -1;

    int flag = wx_bridge_->RemoveChildFromRichtext(env, pageId, ref, parent_ref, richtext_ref);
    if (flag == -1) {
        LOGE("instance destroy JFM must stop RemoveChildFromRichtext");
    }
    return flag;
}
int AndroidSide::UpdateRichtextStyle(const char *pageId, const char *ref,
                                     std::vector<std::pair<std::string, std::string>> *styles, const char *parent_ref,
                                     const char *richtext_ref) {
    JNIEnv *env = base::android::AttachCurrentThread();
    if (env == nullptr)
        return -1;

    int flag = wx_bridge_->UpdateRichtextStyle(env, pageId, ref, styles, parent_ref, richtext_ref);
    if (flag == -1) {
        LOGE("instance destroy JFM must stop UpdateRichtextStyle");
    }
    return flag;
}
int AndroidSide::UpdateRichtextChildAttr(const char *pageId, const char *ref,
                                         std::vector<std::pair<std::string, std::string>> *attributes,
                                         const char *parent_ref, const char *richtext_ref) {
    JNIEnv *env = base::android::AttachCurrentThread();
    if (env == nullptr)
        return -1;

    int flag = wx_bridge_->UpdateRichtextChildAttr(env, pageId, ref, attributes, parent_ref, richtext_ref);
    if (flag == -1) {
        LOGE("instance destroy JFM must stop UpdateRichtextChildAttr");
    }
    return flag;
}

std::unique_ptr<ValueWithType> AndroidSide::CallNativeModule(
    const char *page_id, const char *module, const char *method,
    const char *arguments, int arguments_length, const char *options,
    int options_length) {
  std::unique_ptr<ValueWithType> ipc_result(new ValueWithType());
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return ipc_result;

  auto result =
      wx_bridge_->CallNativeModule(env, page_id, module, method, arguments,
                                   arguments_length, options, options_length);

  ipc_result->type = ParamsType::INT32;
  ipc_result->value.int32Value = -1;
  if (result.IsNull()) {
    return ipc_result;
  }

  auto wx_js_object_result =
      std::unique_ptr<WXJSObject>(new WXJSObject(env, result.Get()));
  jint jTypeInt = wx_js_object_result->GetType(env);
  auto jDataObj = wx_js_object_result->GetData(env);

  if (jTypeInt == 1) {
    ipc_result->type = ParamsType::DOUBLE;
    ipc_result->value.doubleValue =
        base::android::JNIType::DoubleValue(env, jDataObj.Get());
  } else if (jTypeInt == 2) {
    jstring jDataStr = (jstring)jDataObj.Get();
    ipc_result->type = ParamsType::STRING;
    ipc_result->value.string = jstring2WeexString(env, jDataStr);
  } else if (jTypeInt == 3) {
    jstring jDataStr = (jstring)jDataObj.Get();
    ipc_result->type = ParamsType::JSONSTRING;
    ipc_result->value.string = jstring2WeexString(env, jDataStr);
  } else if (jTypeInt == 4) {
    jbyteArray array = (jbyteArray)jDataObj.Get();
    if (array != nullptr) {
      int length = env->GetArrayLength(array);
      void *data = env->GetByteArrayElements(array, 0);
      ipc_result->type = ParamsType::BYTEARRAY;
      ipc_result->value.byteArray =
          genWeexByteArray((const char *)data, length);
      env->ReleaseByteArrayElements(array, (jbyte *)data, 0);
    }
  }

  return ipc_result;
}

void AndroidSide::CallNativeComponent(const char *page_id, const char *ref,
                                      const char *method, const char *arguments,
                                      int arguments_length, const char *options,
                                      int options_length) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return;

  wx_bridge_->CallNativeComponent(env, page_id, ref, method, arguments,
                                  arguments_length, options, options_length);
}

void AndroidSide::SetTimeout(const char *callback_id, const char *time) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return;

  wx_bridge_->SetTimeout(env, callback_id, time);
}

void AndroidSide::NativeLog(const char *str_array) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return;

  LogUtils::NativeLog(env, str_array);
}

int AndroidSide::UpdateFinish(const char *page_id, const char *task,
                              int taskLen, const char *callback,
                              int callbackLen) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return -1;

  int flag = wx_bridge_->UpdateFinish(env, page_id, task, callback);
  if (flag == -1) {
    LOGE("instance destroy JFM must stop callUpdateFinish");
  }
  return flag;
}

int AndroidSide::RefreshFinish(const char *page_id, const char *task,
                               const char *callback) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return -1;

  int flag = wx_bridge_->RefreshFinish(env, page_id, task, callback);

  if (flag == -1) {
    LOGE("instance destroy JFM must stop callNative");
  }
  return flag;
}

int AndroidSide::AddEvent(const char *page_id, const char *ref,
                          const char *event) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return -1;

  int flag = wx_bridge_->AddEvent(env, page_id, ref, event);
  if (flag == -1) {
    LOGE("instance destroy JFM must stop callAddEvent");
  }
  return flag;
}

int AndroidSide::RemoveEvent(const char *page_id, const char *ref,
                             const char *event) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return -1;

  int flag = wx_bridge_->RemoveEvent(env, page_id, ref, event);
  if (flag == -1) {
    LOGE("instance destroy JFM must stop callRemoveElement");
  }
  return flag;
}

int AndroidSide::CreateBody(const char *page_id, const char *component_type,
                            const char *ref,
                            std::map<std::string, std::string> *styles,
                            std::map<std::string, std::string> *attributes,
                            std::set<std::string> *events,
                            const WXCoreMargin &margins,
                            const WXCorePadding &paddings,
                            const WXCoreBorderWidth &borders) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return -1;

  int flag =
      wx_bridge_->CreateBody(env, page_id, component_type, ref, styles,
                             attributes, events, margins, paddings, borders);
  if (flag == -1) {
    LOGE("instance destroy JFM must stop callCreateBody");
  }
  return flag;
}

int AndroidSide::AddElement(const char *page_id, const char *component_type,
                            const char *ref, int &index, const char *parentRef,
                            std::map<std::string, std::string> *styles,
                            std::map<std::string, std::string> *attributes,
                            std::set<std::string> *events,
                            const WXCoreMargin &margins,
                            const WXCorePadding &paddings,
                            const WXCoreBorderWidth &borders, bool willLayout) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return -1;

  int flag = wx_bridge_->AddElement(env, page_id, component_type, ref, index,
                                    parentRef, styles, attributes, events,
                                    margins, paddings, borders, willLayout);

  if (flag == -1) {
    LOGE("instance destroy JFM must stop callAddElement");
  }
  return flag;
}

int AndroidSide::Layout(const char *page_id, const char *ref, float top,
                        float bottom, float left, float right, float height,
                        float width, bool isRTL, int index) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return -1;

  int flag = 0;
  wx_bridge_->Layout(env, page_id, ref, top, bottom, left, right,
                     height, width, isRTL, index);

  if (flag == -1) {
    LOGE("instance destroy JFM must stop callLayout");
  }
  return flag;
}

int AndroidSide::UpdateStyle(
    const char *page_id, const char *ref,
    std::vector<std::pair<std::string, std::string>> *style,
    std::vector<std::pair<std::string, std::string>> *margin,
    std::vector<std::pair<std::string, std::string>> *padding,
    std::vector<std::pair<std::string, std::string>> *border) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return -1;

  int flag = wx_bridge_->UpdateStyle(env, page_id, ref, style, margin, padding,
                                     border);
  if (flag == -1) {
    LOGE("instance destroy JFM must stop callUpdateStyle");
  }
  return flag;
}

int AndroidSide::UpdateAttr(
    const char *page_id, const char *ref,
    std::vector<std::pair<std::string, std::string>> *attrs) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return -1;

  int flag = 0;
  flag = wx_bridge_->UpdateAttr(env, page_id, ref, attrs);
  if (flag == -1) {
    LOGE("instance destroy JFM must stop callUpdateStyle");
  }
  return flag;
}

int AndroidSide::CreateFinish(const char *page_id) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return -1;

  int flag = wx_bridge_->CreateFinish(env, page_id);

  if (flag == -1) {
    LOGE("instance destroy JFM must stop callCreateFinish");
  }
  return flag;
}

int AndroidSide::RenderSuccess(const char *page_id) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return -1;

  int flag = wx_bridge_->RenderSuccess(env, page_id);

  if (flag == -1) {
    LOGE("instance destroy JFM must stop callRenderFinish");
  }
  return flag;
}

int AndroidSide::RemoveElement(const char *page_id, const char *ref) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return -1;

  int flag = wx_bridge_->RemoveElement(env, page_id, ref);
  if (flag == -1) {
    LOGE("instance destroy JFM must stop callRemoveElement");
  }
  return flag;
}

int AndroidSide::MoveElement(const char *page_id, const char *ref,
                             const char *parent_ref, int index) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return -1;

  int flag = wx_bridge_->MoveElement(env, page_id, ref, parent_ref, index);
  if (flag == -1) {
    LOGE("instance destroy JFM must stop callRemoveElement");
  }
  return flag;
}

int AndroidSide::AppendTreeCreateFinish(const char *page_id, const char *ref) {
  JNIEnv *env = base::android::AttachCurrentThread();
  int flag = wx_bridge_->AppendTreeCreateFinish(env, page_id, ref);
  if (flag == -1) {
    LOGE("instance destroy JFM must stop callAppendTreeCreateFinish");
  }
  return flag;
}

int AndroidSide::HasTransitionPros(
    const char *page_id, const char *ref,
    std::vector<std::pair<std::string, std::string>> *style) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return -1;

  if (style != nullptr) {
    return wx_bridge_->HasTransitionPros(env, page_id, ref, *style);
  } else {
    return wx_bridge_->HasTransitionPros(
        env, page_id, ref, std::vector<std::pair<std::string, std::string>>());
  }
}

void AndroidSide::PostMessage(const char *vm_id, const char *data, int dataLength) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return;

  wml_bridge_->PostMessage(env, vm_id, data, dataLength);
}

void AndroidSide::DispatchMessage(const char *client_id,
                                  const char *data, int dataLength, const char *callback, const char *vm_id) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return;

  wml_bridge_->DispatchMessage(env, client_id,  data, dataLength, callback, vm_id);
}

std::unique_ptr<WeexJSResult> AndroidSide::DispatchMessageSync(
    const char *client_id, const char *data, int dataLength,
    const char *vm_id) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return std::unique_ptr<WeexJSResult>();

  auto jni_result =
      wml_bridge_->DispatchMessageSync(env, client_id, data, dataLength, vm_id);
  JByteArrayRef byte_array(env, jni_result.Get());
  char *copy = nullptr;
  if (byte_array.length() > 0) {
    copy = new char[byte_array.length()];
    strcpy(copy, byte_array.getBytes());
  }
  return std::unique_ptr<WeexJSResult>(
      new WeexJSResult(std::unique_ptr<char[]>(copy), byte_array.length()));
}

void AndroidSide::OnReceivedResult(long callback_id, std::unique_ptr<WeexJSResult>& result) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return;

  wx_bridge_->OnReceivedResult(env, callback_id,  result);
}

jobject AndroidSide::getMeasureFunc(const char *pageId, jlong renderObjectPtr) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return nullptr;

  return wx_bridge_->GetMeasureFunc(env, pageId, renderObjectPtr).Release();
}
void AndroidSide::SetPageDirty(const char *page_id, bool dirty) {
  JNIEnv *env = base::android::AttachCurrentThread();
  if (env == nullptr)
    return;

  wx_bridge_->SetPageDirty(env, page_id, dirty);
}
}  // namespace WeexCore
