// 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.

use std::collections::HashMap;

use jni::JNIEnv;
use jni::objects::JObject;
use jni::objects::JValue;
use jni::sys::jboolean;
use jni::sys::jint;
use jni::sys::jlong;
use opendal::Entry;
use opendal::EntryMode;
use opendal::Metadata;
use opendal::OperatorInfo;
use opendal::raw::PresignedRequest;
use opendal::{Capability, Error, ErrorKind};

mod async_operator;
mod convert;
mod error;
mod executor;
mod layer;
mod operator;
mod operator_input_stream;
mod operator_output_stream;
mod utility;

pub(crate) type Result<T> = std::result::Result<T, error::Error>;

fn make_presigned_request<'a>(env: &mut JNIEnv<'a>, req: PresignedRequest) -> Result<JObject<'a>> {
    let method = env.new_string(req.method().as_str())?;
    let uri = env.new_string(req.uri().to_string())?;
    let headers = {
        let mut map = HashMap::new();
        for (k, v) in req.header().iter() {
            let key = k.to_string();
            let value = v.to_str().map_err(|err| {
                opendal::Error::new(opendal::ErrorKind::Unexpected, err.to_string())
            })?;
            map.insert(key, value.to_owned());
        }
        map
    };
    let headers = convert::hashmap_to_jmap(env, &headers)?;
    let result = env.new_object(
        "org/apache/opendal/PresignedRequest",
        "(Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)V",
        &[
            JValue::Object(&method),
            JValue::Object(&uri),
            JValue::Object(&headers),
        ],
    )?;
    Ok(result)
}

fn make_operator_info<'a>(env: &mut JNIEnv<'a>, info: OperatorInfo) -> Result<JObject<'a>> {
    let scheme = env.new_string(info.scheme().to_string())?;
    let root = env.new_string(info.root().to_string())?;
    let name = env.new_string(info.name().to_string())?;
    let full_capability_obj = make_capability(env, info.full_capability())?;
    let native_capability_obj = make_capability(env, info.native_capability())?;

    let result = env
        .new_object(
            "org/apache/opendal/OperatorInfo",
            "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lorg/apache/opendal/Capability;Lorg/apache/opendal/Capability;)V",
            &[
                JValue::Object(&scheme),
                JValue::Object(&root),
                JValue::Object(&name),
                JValue::Object(&full_capability_obj),
                JValue::Object(&native_capability_obj),
            ],
        )?;
    Ok(result)
}

fn make_capability<'a>(env: &mut JNIEnv<'a>, cap: Capability) -> Result<JObject<'a>> {
    let capability = env.new_object(
        "org/apache/opendal/Capability",
        "(ZZZZZZZZZZZZZZZZZZZZZZJJZZZZZZZZZZZZZZZ)V",
        &[
            JValue::Bool(cap.stat as jboolean),
            JValue::Bool(cap.stat_with_if_match as jboolean),
            JValue::Bool(cap.stat_with_if_none_match as jboolean),
            JValue::Bool(cap.stat_with_if_modified_since as jboolean),
            JValue::Bool(cap.stat_with_if_unmodified_since as jboolean),
            JValue::Bool(cap.stat_with_version as jboolean),
            JValue::Bool(cap.read as jboolean),
            JValue::Bool(cap.read_with_if_match as jboolean),
            JValue::Bool(cap.read_with_if_none_match as jboolean),
            JValue::Bool(cap.read_with_override_cache_control as jboolean),
            JValue::Bool(cap.read_with_override_content_disposition as jboolean),
            JValue::Bool(cap.read_with_override_content_type as jboolean),
            JValue::Bool(cap.write as jboolean),
            JValue::Bool(cap.write_can_multi as jboolean),
            JValue::Bool(cap.write_can_append as jboolean),
            JValue::Bool(cap.write_with_content_type as jboolean),
            JValue::Bool(cap.write_with_content_disposition as jboolean),
            JValue::Bool(cap.write_with_cache_control as jboolean),
            JValue::Bool(cap.write_with_if_match as jboolean),
            JValue::Bool(cap.write_with_if_none_match as jboolean),
            JValue::Bool(cap.write_with_if_not_exists as jboolean),
            JValue::Bool(cap.write_with_user_metadata as jboolean),
            JValue::Long(convert::usize_to_jlong(cap.write_multi_max_size)),
            JValue::Long(convert::usize_to_jlong(cap.write_multi_min_size)),
            JValue::Bool(cap.create_dir as jboolean),
            JValue::Bool(cap.delete as jboolean),
            JValue::Bool(cap.copy as jboolean),
            JValue::Bool(cap.rename as jboolean),
            JValue::Bool(cap.list as jboolean),
            JValue::Bool(cap.list_with_limit as jboolean),
            JValue::Bool(cap.list_with_start_after as jboolean),
            JValue::Bool(cap.list_with_recursive as jboolean),
            JValue::Bool(cap.list_with_versions as jboolean),
            JValue::Bool(cap.list_with_deleted as jboolean),
            JValue::Bool(cap.presign as jboolean),
            JValue::Bool(cap.presign_read as jboolean),
            JValue::Bool(cap.presign_stat as jboolean),
            JValue::Bool(cap.presign_write as jboolean),
            JValue::Bool(cap.shared as jboolean),
        ],
    )?;
    Ok(capability)
}

fn make_metadata<'a>(env: &mut JNIEnv<'a>, metadata: Metadata) -> Result<JObject<'a>> {
    let mode = match metadata.mode() {
        EntryMode::FILE => 0,
        EntryMode::DIR => 1,
        EntryMode::Unknown => 2,
    };

    let last_modified = metadata.last_modified().map_or_else(
        || Ok::<JObject<'_>, error::Error>(JObject::null()),
        |v| {
            Ok(env
                .call_static_method(
                    "java/time/Instant",
                    "ofEpochSecond",
                    "(JJ)Ljava/time/Instant;",
                    &[
                        JValue::Long(v.into_inner().as_second()),
                        JValue::Long(v.into_inner().subsec_nanosecond() as jlong),
                    ],
                )?
                .l()?)
        },
    )?;

    let cache_control = convert::string_to_jstring(env, metadata.cache_control())?;

    let content_disposition = convert::string_to_jstring(env, metadata.content_disposition())?;

    let content_md5 = convert::string_to_jstring(env, metadata.content_md5())?;

    let content_type = convert::string_to_jstring(env, metadata.content_type())?;

    let etag = convert::string_to_jstring(env, metadata.etag())?;

    let version = convert::string_to_jstring(env, metadata.version())?;

    let content_length = metadata.content_length() as jlong;

    let result = env
        .new_object(
            "org/apache/opendal/Metadata",
            "(IJLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/time/Instant;Ljava/lang/String;)V",
            &[
                JValue::Int(mode as jint),
                JValue::Long(content_length),
                JValue::Object(&content_disposition),
                JValue::Object(&content_md5),
                JValue::Object(&content_type),
                JValue::Object(&cache_control),
                JValue::Object(&etag),
                JValue::Object(&last_modified),
                JValue::Object(&version),
            ],
        )?;
    Ok(result)
}

fn make_entry<'a>(env: &mut JNIEnv<'a>, entry: Entry) -> Result<JObject<'a>> {
    let path = env.new_string(entry.path())?;
    let metadata = make_metadata(env, entry.metadata().to_owned())?;

    Ok(env.new_object(
        "org/apache/opendal/Entry",
        "(Ljava/lang/String;Lorg/apache/opendal/Metadata;)V",
        &[JValue::Object(&path), JValue::Object(&metadata)],
    )?)
}

fn make_write_options<'a>(
    env: &mut JNIEnv<'a>,
    options: &JObject,
) -> Result<opendal::options::WriteOptions> {
    let concurrent = match convert::read_int_field(env, options, "concurrent")? {
        v if v > 0 => v as usize,
        v => {
            return Err(Error::new(
                ErrorKind::Unexpected,
                format!("Concurrent must be positive, instead got: {v}"),
            )
            .into());
        }
    };
    Ok(opendal::options::WriteOptions {
        append: convert::read_bool_field(env, options, "append").unwrap_or_default(),
        content_type: convert::read_string_field(env, options, "contentType")?,
        content_disposition: convert::read_string_field(env, options, "contentDisposition")?,
        content_encoding: convert::read_string_field(env, options, "contentEncoding")?,
        cache_control: convert::read_string_field(env, options, "cacheControl")?,
        if_match: convert::read_string_field(env, options, "ifMatch")?,
        if_none_match: convert::read_string_field(env, options, "ifNoneMatch")?,
        if_not_exists: convert::read_bool_field(env, options, "ifNotExists").unwrap_or_default(),
        user_metadata: convert::read_map_field(env, options, "userMetadata")?,
        concurrent,
        chunk: convert::read_jlong_field_to_usize(env, options, "chunk")?,
    })
}

fn make_list_options<'a>(
    env: &mut JNIEnv<'a>,
    options: &JObject,
) -> Result<opendal::options::ListOptions> {
    Ok(opendal::options::ListOptions {
        limit: convert::read_jlong_field_to_usize(env, options, "limit")?,
        start_after: convert::read_string_field(env, options, "startAfter")?,
        recursive: convert::read_bool_field(env, options, "recursive").unwrap_or_default(),
        versions: convert::read_bool_field(env, options, "versions").unwrap_or_default(),
        deleted: convert::read_bool_field(env, options, "deleted").unwrap_or_default(),
    })
}

fn make_stat_options(env: &mut JNIEnv, options: &JObject) -> Result<opendal::options::StatOptions> {
    Ok(opendal::options::StatOptions {
        if_match: convert::read_string_field(env, options, "ifMatch")?,
        if_none_match: convert::read_string_field(env, options, "ifNoneMatch")?,
        if_modified_since: convert::read_instant_field_to_timestamp(
            env,
            options,
            "ifModifiedSince",
        )?,
        if_unmodified_since: convert::read_instant_field_to_timestamp(
            env,
            options,
            "ifUnmodifiedSince",
        )?,
        version: convert::read_string_field(env, options, "version")?,
        override_content_type: convert::read_string_field(env, options, "overrideContentType")?,
        override_cache_control: convert::read_string_field(env, options, "overrideCacheControl")?,
        override_content_disposition: convert::read_string_field(
            env,
            options,
            "overrideContentDisposition",
        )?,
    })
}

fn make_read_options<'a>(
    env: &mut JNIEnv<'a>,
    options: &JObject,
) -> Result<opendal::options::ReadOptions> {
    let offset = convert::read_int64_field(env, options, "offset")?;
    let length = convert::read_int64_field(env, options, "length")?;

    Ok(opendal::options::ReadOptions {
        range: convert::offset_length_to_range(offset, length)?.into(),
        ..Default::default()
    })
}

fn make_reader_options<'a>(
    _: &mut JNIEnv<'a>,
    _: &JObject,
) -> Result<opendal::options::ReaderOptions> {
    Ok(opendal::options::ReaderOptions::default())
}
