package com.zhgd.xmgl.util;

import cn.hutool.json.JSONUtil;
import com.autodesk.client.ApiException;
import com.autodesk.client.ApiResponse;
import com.autodesk.client.api.BucketsApi;
import com.autodesk.client.api.DerivativesApi;
import com.autodesk.client.api.ObjectsApi;
import com.autodesk.client.auth.Credentials;
import com.autodesk.client.auth.OAuth2TwoLegged;
import com.autodesk.client.model.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;

/**
 * @program: wisdomSite
 * @description: autodesk
 * @author: Mr.Peng
 * @create: 2020-09-23 14:26
 **/
@Slf4j
public class ForgeUtil {

    //private static final String CLIENT_ID = "zQRl0iGIm6v6JhYr92RgxcAf9TuXp7EW";
    //private static final String CLIENT_SECRET = "0DfZvyRjURMDgpaP";

    private static final String BUCKET_KEY = "forge-java-app-demo-";

    //private static OAuth2TwoLegged oauth2TwoLegged;

    // Initialize the relevant clients; in this example, the Objects, Buckets and Derivatives clients, which are part of the Data Management API and Model Derivatives API

    private static final ObjectsApi objectsApi = new ObjectsApi();

    private static final BucketsApi bucketsApi = new BucketsApi();
    private static final DerivativesApi derivativesApi = new DerivativesApi();

    //private static Credentials twoLeggedCredentials;

    /**
     * Initialize the 2-legged OAuth 2.0 client, and optionally set specific scopes.
     * @throws Exception
     */
    /*private static void initializeOAuth() throws Exception {

        // You must provide at least one valid scope
        List<String> scopes = new ArrayList<String>();
        scopes.add("data:read");
        scopes.add("data:write");
        scopes.add("data:create");
        scopes.add("data:search");
        scopes.add("bucket:create");
        scopes.add("bucket:read");
        scopes.add("bucket:update");
        scopes.add("bucket:delete");

        //Set autoRefresh to `true` to automatically refresh the access token when it expires.
        oauth2TwoLegged = new OAuth2TwoLegged(CLIENT_ID, CLIENT_SECRET, scopes, true);
        twoLeggedCredentials = oauth2TwoLegged.authenticate();
    }*/

    /**
     * Example of how to create a new bucket using Forge SDK.
     * Uses the oauth2TwoLegged and twoLeggedCredentials objects that you retrieved previously.
     *
     * @throws com.autodesk.client.ApiException
     * @throws Exception
     */
    private static void createBucket(OAuth2TwoLegged oauth2TwoLegged, Credentials twoLeggedCredentials, String clientId) throws ApiException, Exception {
        log.info("***** Sending createBucket request");
        PostBucketsPayload payload = new PostBucketsPayload();
        payload.setBucketKey(BUCKET_KEY + clientId.toLowerCase());
        payload.setPolicyKey(PostBucketsPayload.PolicyKeyEnum.PERSISTENT);
        ApiResponse<Bucket> response = bucketsApi.createBucket(payload, "US", oauth2TwoLegged, twoLeggedCredentials);
        log.info("***** Response for createBucket: " + response.getData());
    }

    /**
     * 获取BIM文件的组件
     *
     * @param urn
     * @return
     * @throws ApiException
     * @throws Exception
     */
    public static List<MetadataCollection> getMetadata(String urn, String clientId, String clientSecret) {
        try {
            List<String> scopes = new ArrayList<String>();
            scopes.add("data:read");
            scopes.add("data:write");
            scopes.add("bucket:create");
            scopes.add("bucket:read");
            //Set autoRefresh to `true` to automatically refresh the access token when it expires.
            OAuth2TwoLegged oauth2TwoLegged = new OAuth2TwoLegged(clientId, clientSecret, scopes, true);
            Credentials twoLeggedCredentials = oauth2TwoLegged.authenticate();
            log.info("***** Sending getMetadata request");
            ApiResponse<Metadata> response = derivativesApi.getMetadata(urn, null, oauth2TwoLegged, twoLeggedCredentials);
            ApiResponse<Metadata> aa = derivativesApi.getModelviewMetadata(urn, response.getData().getData().getMetadata().get(0).getGuid(), null, null, oauth2TwoLegged, twoLeggedCredentials);
            ApiResponse<Metadata> data = derivativesApi.getModelviewProperties(urn, response.getData().getData().getMetadata().get(0).getGuid(), null, null, oauth2TwoLegged, twoLeggedCredentials);
            //log.info("***** Response for getMetadata: " + );
            return data.getData().getData().getCollection();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private static ObjectDetails uploadFile(File fileToUpload, String fileName, OAuth2TwoLegged oauth2TwoLegged, Credentials twoLeggedCredentials) throws FileNotFoundException, ApiException, Exception {
        log.info("***** Sending uploadFile request");
        //File fileToUpload = new File(FILE_PATH);
        ApiResponse<ObjectDetails> response = objectsApi.uploadObject(BUCKET_KEY, fileName, (int) fileToUpload.length(), fileToUpload, null, null, oauth2TwoLegged, twoLeggedCredentials);

        log.info("***** Response for uploadFile: ");
        ObjectDetails objectDetails = response.getData();
        log.info("Uploaded object Details - Location: " + objectDetails.getLocation() + ", Size:" + objectDetails.getSize());
        return objectDetails;
    }

    /**
     * Example of how to send a translate to SVF job request.
     * Uses the oauth2TwoLegged and twoLeggedCredentials objects that you retrieved previously.
     *
     * @param urn - the urn of the file to translate
     * @throws com.autodesk.client.ApiException
     * @throws Exception
     */
    private static Job translateToSVF(String urn, OAuth2TwoLegged oauth2TwoLegged, Credentials twoLeggedCredentials) throws ApiException, Exception {
        log.info("***** Sending Derivative API translate request");

        JobPayload job = new JobPayload();

        byte[] urnBase64 = Base64.encodeBase64(urn.getBytes());

        JobPayloadInput input = new JobPayloadInput();
        input.setUrn(new String(urnBase64));

        JobPayloadOutput output = new JobPayloadOutput();
        JobPayloadItem formats = new JobPayloadItem();
        formats.setType(JobPayloadItem.TypeEnum.SVF);
        formats.setViews(Arrays.asList(JobPayloadItem.ViewsEnum._3D));
        output.setFormats(Arrays.asList(formats));

        job.setInput(input);
        job.setOutput(output);

        ApiResponse<Job> response = derivativesApi.translate(job, true, oauth2TwoLegged, twoLeggedCredentials);
        log.info("***** Response for Translating File to SVF: " + response.getData());

        return response.getData();
    }


    public static String getUrn(File file, String fileName, String clientId, String clientSecret) {
        Map<String, Object> data = new HashMap<>();
        String urn = "";
        try {
            List<String> scopes = new ArrayList<String>();
            scopes.add("data:read");
            scopes.add("data:write");
            scopes.add("bucket:create");
            scopes.add("bucket:read");
            //Set autoRefresh to `true` to automatically refresh the access token when it expires.
            OAuth2TwoLegged oauth2TwoLegged = new OAuth2TwoLegged(clientId, clientSecret, scopes, true);
            Credentials twoLeggedCredentials = oauth2TwoLegged.authenticate();

            try {
                createBucket(oauth2TwoLegged, twoLeggedCredentials, clientId);
            } catch (ApiException e) {
                System.err.println("Error creating bucket : " + e.getResponseBody());
            }
            try {
                ObjectDetails uploadedObject = uploadFile(file, fileName, oauth2TwoLegged, twoLeggedCredentials);
                try {
                    Job job = translateToSVF(uploadedObject.getObjectId(), oauth2TwoLegged, twoLeggedCredentials);
                    if (job.getResult().equals("success")) {
                        //String base64Urn = job.getUrn();
                        urn = job.getUrn();
                        log.info("------------: " + urn);
                    }
                } catch (ApiException e) {
                    System.err.println("Error translating file : " + e.getResponseBody());
                }
            } catch (ApiException e) {
                System.err.println("Error uploading filessss : " + e.getCode());
            }
        } catch (ApiException e) {
            System.err.println("Error Initializing OAuth client : " + e.getResponseBody());
        } catch (Exception e) {
            System.err.println("System Error ");
        }

        //data.put("urn",urn);
        return urn;

    }

    public static String getToken(String clientId, String clientSecret) throws Exception {
        List<String> scopes = new ArrayList<String>();
        scopes.add("data:read");
        scopes.add("data:write");
        scopes.add("bucket:create");
        scopes.add("bucket:read");
        //Set autoRefresh to `true` to automatically refresh the access token when it expires.
        OAuth2TwoLegged oauth2TwoLegged = new OAuth2TwoLegged(clientId, clientSecret, scopes, true);
        Credentials twoLeggedCredentials = oauth2TwoLegged.authenticate();
        return twoLeggedCredentials.getAccessToken();
    }

    public static void main(String[] args) {
        log.info(JSONUtil.toJsonStr(getMetadata("dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6Zm9yZ2UtamF2YS1hcHAtZGVtby16cXJsMGlnaW02djZqaHlyOTJyZ3hjYWY5dHV4cDdldy90ZXN0Mi5vYmo", "zQRl0iGIm6v6JhYr92RgxcAf9TuXp7EW", "0DfZvyRjURMDgpaP")));
    }
}
