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

package org.apache.james.linshare.client;

import static org.apache.james.linshare.client.LinshareAPI.Headers.ACCEPT_APPLICATION_JSON;
import static org.apache.james.linshare.client.LinshareAPI.Headers.CONTENT_TYPE_APPLICATION_JSON;
import static org.apache.james.linshare.client.LinshareAPI.Headers.CONTENT_TYPE_MULTIPART;

import java.io.File;

import org.apache.james.linshare.LinshareConfiguration;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;

import feign.Feign;
import feign.Logger;
import feign.Param;
import feign.RequestLine;
import feign.auth.BasicAuthRequestInterceptor;
import feign.form.FormEncoder;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;
import feign.slf4j.Slf4jLogger;

public interface LinshareAPI {

    interface Headers {
        String ACCEPT_APPLICATION_JSON = "Accept: application/json";
        String CONTENT_TYPE_MULTIPART = "Content-Type: multipart/form-data";
        String CONTENT_TYPE_APPLICATION_JSON = "Content-Type: application/json";
    }

    @VisibleForTesting
    static LinshareAPI from(LinshareConfiguration configuration) {
        return Feign.builder()
            .requestInterceptor(
                new BasicAuthRequestInterceptor(
                    configuration.getUuid().toString(),
                    configuration.getPassword()))
            .logger(new Slf4jLogger(LinshareAPI.class))
            .logLevel(Logger.Level.FULL)
            .encoder(new FormEncoder(new JacksonEncoder()))
            .decoder(new JacksonDecoder())
            .target(LinshareAPI.class, configuration.getUrl().toString());
    }

    @RequestLine("GET /linshare/webservice/rest/delegation/v2/users/{targetUserMail}")
    @feign.Headers({ ACCEPT_APPLICATION_JSON, CONTENT_TYPE_APPLICATION_JSON })
    User getUserByMail(@Param("targetUserMail") String mail);

    @RequestLine("POST linshare/webservice/rest/delegation/v2/{userUuid}/documents")
    @feign.Headers({ ACCEPT_APPLICATION_JSON, CONTENT_TYPE_MULTIPART })
    Document uploadDocumentByDelegation(@Param("userUuid") String userUuid, @Param("file") File file, @Param("filesize") long fileSize);

    default Document uploadDocumentByDelegation(User targetUser, File file) {
        Preconditions.checkNotNull(file);
        Preconditions.checkArgument(file.exists(), "File to upload does not exist: %s", file.getAbsolutePath());

        return uploadDocumentByDelegation(targetUser.getUuid(), file, file.length());
    }
}
