/*
 * Copyright 2015-2016 IBM Corporation
 *
 * 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.
 */
package system;

import com.cloudant.client.api.CloudantClient;
import com.cloudant.client.api.Database;
import com.google.gson.*;
import com.jayway.restassured.response.Response;
import common.Pair;
import common.TestUtils;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Date;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;

import static com.jayway.restassured.RestAssured.given;
import static org.junit.Assert.assertTrue;

/**
 * Basic tests of the cloudant trigger function.
 */
public class CloudantUtil {
    public static final String USER_PROPERTY = "user";
    public static final String PWD_PROPERTY = "password";
    public static final String DBNAME_PROPERTY = "dbname";
    public static final String DOC_ID = "testId";

    /**
     * The root of the Cloudant installation.
     */
    private static final String CLOUDANT_INSTALL_FILE = "installCatalog.sh";
    private static final String CLOUDANT_HOME = getCloudantHome();
    public static final File ATTACHMENT_FILE_PATH = getFileRelativeToCloudantHome("tests/dat/attach.txt");
    public static final File INDEX_DDOC_PATH = getFileRelativeToCloudantHome("tests/dat/indexdesigndoc.txt");
    public static final File VIEW_AND_SEARCH_DDOC_PATH = getFileRelativeToCloudantHome("tests/dat/searchdesigndoc.txt");


    private static Gson gson = new Gson();

    public static class Credential {
        public final String user;
        public final String password;
        public final String dbname;

        public String host() {
            return user + ".cloudant.com";
        }

        public Credential(String user, String password, String dbname) {
            this.user = user;
            this.password = password;
            this.dbname = dbname;
        }

        public Credential(Properties props) {
            this(props.getProperty(USER_PROPERTY), props.getProperty(PWD_PROPERTY), props.getProperty(DBNAME_PROPERTY));
        }

        public static Credential makeFromVCAPFile(String vcapService, String dbNamePrefix) {
            // Create database name using dbNamePrefix and generated uuid
            String uniqueSuffix = UUID.randomUUID().toString().replace("-", "");
            String dbname = dbNamePrefix.toLowerCase() + "-" + uniqueSuffix;

            Map<String,String> credentials = TestUtils.getVCAPcredentials(vcapService);
            String username = credentials.get("username");
            String password = credentials.get("password");
            Properties props = new Properties();
            props.setProperty(USER_PROPERTY, username);
            props.setProperty(PWD_PROPERTY, password);
            props.setProperty(DBNAME_PROPERTY, dbname);
            return new Credential(props);
        }

    }

    public static void setUp(Credential credential) throws Exception {
        deleteTestDatabase(credential);
        for (int i = 0; i < 5; i++) {
            try {
                Pair<Integer, JsonObject> response = CloudantUtil.createTestDatabase(credential, false);
                if (response.fst == 201)
                    return;
                // respond code is sometimes not 201 but still ok
                // (might be 200 or 202)
                if (response.snd.has("ok")) {
                    if (response.snd.get("ok").getAsBoolean())
                        return;
                }
                if (response.snd.has("reason")) {
                    String reason = response.snd.get("reason").getAsString();
                    if (reason.contains("exists"))
                        return;
                }
            } catch (Throwable t) {
                Thread.sleep(1000);
            }
        }
        assertTrue("failed to create database " + credential.dbname, false);
    }

    public static void unsetUp(Credential credential) throws Exception {
        deleteTestDatabase(credential);
    }

    /**
     * Delete a user-specific Cloudant database.
     *
     * @throws UnsupportedEncodingException
     * @throws InterruptedException
     */
    public static JsonObject deleteTestDatabase(Credential credential) throws UnsupportedEncodingException, InterruptedException {
        return deleteTestDatabase(credential, null);
    }

    public static JsonObject deleteTestDatabase(Credential credential, String dbName) throws UnsupportedEncodingException, InterruptedException {
        // Use DELETE to delete the database.
        // This could fail if the database already exists, but that's ok.
        Response response = null;
        String db = (dbName != null && !dbName.isEmpty()) ? dbName : credential.dbname;
        assertTrue("failed to determine database name", db != null && !db.isEmpty());
        response = given().port(443).baseUri(cloudantAccount(credential.user)).auth().basic(credential.user, credential.password).when().delete("/" + db);
        System.out.format("Response of delete database %s: %s\n", db, response.asString());
        return (JsonObject) new JsonParser().parse(response.asString());
    }

    /**
     * Create a user-specific Cloudant database that will be used for this test.
     *
     * @throws UnsupportedEncodingException
     */
    public static Pair<Integer, JsonObject> createTestDatabase(Credential credential) throws UnsupportedEncodingException {
        return createTestDatabase(credential, true);
    }

    private static Pair<Integer, JsonObject> createTestDatabase(Credential credential, boolean failIfCannotCreate) throws UnsupportedEncodingException {
        // Use PUT to create the database.
        // This could fail if the database already exists, but that's ok.
        String dbName = credential.dbname;
        assertTrue("failed to determine database name", dbName != null && !dbName.isEmpty());
        Response response = given().port(443).baseUri(cloudantAccount(credential.user)).auth().basic(credential.user, credential.password).when().put("/" + dbName);
        System.out.format("Response of create database %s: %s\n", dbName, response.asString());
        if (failIfCannotCreate)
            assertTrue("failed to create database " + dbName, response.statusCode() == 201 || response.statusCode() == 202);
        return Pair.make(response.statusCode(), (JsonObject) new JsonParser().parse(response.asString()));
    }

    /**
     * read a user-specific Cloudant database to verify database action test
     * cases.
     *
     * @throws UnsupportedEncodingException
     */
    public static JsonObject readTestDatabase(Credential credential) {
        try {
            String db = credential.dbname;
            Response response = given().port(443).baseUri(cloudantAccount(credential.user)).auth().basic(credential.user, credential.password).when().get("/" + db);
            System.out.format("Response of HTTP GET for database %s: %s\n", credential.dbname, response.asString());
            return gson.fromJson(response.asString(), JsonObject.class);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static Response readTestDatabase(Credential credential, String dbName) {
        try {
            String db = (dbName != null && !dbName.isEmpty()) ? dbName : credential.dbname;
            Response response = given().port(443).baseUri(cloudantAccount(credential.user)).auth().basic(credential.user, credential.password).when().get("/" + db);
            System.out.format("Response of HTTP GET for database %s: %s\n", credential.dbname, response.asString());
            return response;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * create a document in the cloudant database
     *
     * @throws UnsupportedEncodingException
     */
    public static JsonObject createDocument(Credential credential, String jsonObj) throws UnsupportedEncodingException {
        JsonObject obj = new JsonParser().parse(jsonObj).getAsJsonObject();

        CloudantClient client = new CloudantClient(credential.user, credential.user, credential.password);
        Database db = client.database(credential.dbname, false);
        com.cloudant.client.api.model.Response res = db.post(obj);
        client.shutdown();

        JsonObject ret = new JsonObject();
        ret.addProperty("ok", true);
        ret.addProperty("id", res.getId());
        ret.addProperty("rev", res.getRev());
        return ret;
    }

    /**
     * get a document from the cloudant database
     *
     * @throws UnsupportedEncodingException
     */
    public static JsonObject getDocument(Credential credential, String docId) throws UnsupportedEncodingException {
        // use GET to get the document
        Response response = given().port(443).baseUri(cloudantAccount(credential.user)).auth().basic(credential.user, credential.password).get("/" + credential.dbname + "/" + docId);
        String responseStr = response.asString();
        if (responseStr.length() > 500)
            responseStr = responseStr.substring(0, 500);
        System.out.format("Response of get document from database %s: %s\n", credential.dbname, responseStr);
        return (JsonObject) new JsonParser().parse(response.asString());
    }

    /**
     * delete a document from the cloudant database
     *
     * @throws UnsupportedEncodingException
     */
    public static JsonObject deleteDocument(Credential credential, String docId) throws UnsupportedEncodingException {
        // use GET to get the document
        Response response = given().port(443).baseUri(cloudantAccount(credential.user)).auth().basic(credential.user, credential.password).delete("/" + credential.dbname + "/" + docId);
        System.out.format("Response of delete document in database %s: %s\n", credential.dbname, response.asString());
        assertTrue("failed to delete document in database " + credential.dbname, response.statusCode() == 200 || response.statusCode() == 202);
        return (JsonObject) new JsonParser().parse(response.asString());
    }

    /**
     * Read bulk documents from the cloudant database
     *
     * @throws UnsupportedEncodingException
     */
    public static JsonArray bulkDocuments(Credential credential, JsonArray bulkDocs) throws UnsupportedEncodingException {
        JsonObject docs = new JsonObject();
        docs.add("docs", bulkDocs);
        // use GET to get the document
        String dbname = credential.dbname;
        Response response = given().port(443).baseUri(cloudantAccount(credential.user)).auth().basic(credential.user, credential.password).contentType("application/json").body(docs).post("/" + credential.dbname + "/_bulk_docs?include_docs=true");
        String responseStr = response.asString();
        if (responseStr.length() > 500)
            responseStr = responseStr.substring(0, 500);
        System.out.format("Response of get document from database %s: %s\n", dbname, responseStr);
        return (JsonArray) new JsonParser().parse(response.asString());
    }

    public static JsonObject createDocParameterForWhisk() {
        return createDocParameterForWhisk(null);
    }

    public static JsonObject createDocParameterForWhisk(String doc) {
        JsonObject cloudantDoc = new JsonObject();
        String now = new Date().toString();
        cloudantDoc.addProperty("_id", DOC_ID);
        cloudantDoc.addProperty("date", now);
        // Create JSON object that will be passed as an argument to whisk cli
        JsonObject param = new JsonObject();
        if (doc != null && !doc.isEmpty()) {
            param.addProperty("doc", doc);
        } else {
            param.addProperty("doc", cloudantDoc.toString());
        }
        return param;
    }

    public static JsonArray createDocumentArray(int numDocs) {
        // Array of docs for bulk
        JsonArray bulkDocs = new JsonArray();
        for (int i = 1; i <= numDocs; i++) {
            JsonObject cloudantDoc = new JsonObject();
            String now = new Date().toString();
            cloudantDoc.addProperty("_id", CloudantUtil.DOC_ID + i);
            cloudantDoc.addProperty("date", now);
            bulkDocs.add(cloudantDoc);
        }
        return bulkDocs;
    }

    /**
     * Only keep _id and _rev for each document in the JSON array.
     */
    public static JsonArray updateDocsWithOnlyIdAndRev(JsonArray docs) {
        for (int i = 0; i < docs.size(); i++) {
            JsonElement id = docs.get(i).getAsJsonObject().get("id");
            JsonElement rev = docs.get(i).getAsJsonObject().get("rev");
            docs.get(i).getAsJsonObject().add("_id", id);
            docs.get(i).getAsJsonObject().add("_rev", rev);
        }
        return docs;
    }

    public static JsonArray addDeletedPropertyToDocs(JsonArray docs) {
        for (int i = 0; i < docs.size(); i++) {
            JsonElement id = docs.get(i).getAsJsonObject().get("id");
            JsonElement rev = docs.get(i).getAsJsonObject().get("rev");
            docs.get(i).getAsJsonObject().add("_id", id);
            docs.get(i).getAsJsonObject().add("_rev", rev);
            docs.get(i).getAsJsonObject().addProperty("_deleted", true);
        }
        return docs;
    }

    public static JsonObject createDesignFromFile(File jsonFile) throws JsonSyntaxException, IOException {
        return gson.fromJson(readFile(jsonFile), JsonObject.class);
    }

    public static String readFile(File jsonFile) throws IOException {
        return new String(Files.readAllBytes(jsonFile.toPath()), StandardCharsets.UTF_8);
    }

    /**
     * Create an index in the cloudant database
     *
     * @throws UnsupportedEncodingException
     */
    public static JsonObject createIndex(Credential credential, String jsonObj) throws UnsupportedEncodingException {
        Response response = given().port(443).baseUri(cloudantAccount(credential.user)).auth().basic(credential.user, credential.password).contentType("application/json").body(jsonObj).when().post("/" + credential.dbname + "/_index");
        System.out.format("Response of create document in database %s: %s\n", credential.dbname, response.asString());
        assertTrue("failed to create index in database " + credential.dbname, response.statusCode() == 200);
        return (JsonObject) new JsonParser().parse(response.asString());
    }

    /**
     * Create a document with attachment in a cloudant database
     *
     * @throws UnsupportedEncodingException
     * @throws FileNotFoundException
     */
    public static com.cloudant.client.api.model.Response createDocumentWithAttachment(Credential credential, File attachmentFilePath) throws UnsupportedEncodingException, FileNotFoundException {
        InputStream attachStream = new FileInputStream(attachmentFilePath);
        String contentType = "text/plain";

        CloudantClient client = new CloudantClient(credential.user, credential.user, credential.password);
        Database db = client.database(credential.dbname, false);
        return db.saveAttachment(attachStream, attachmentFilePath.getName(), contentType);
    }

    private static String cloudantAccount(String user) {
        return "https://" + user + ".cloudant.com";
    }

    public static File getFileRelativeToCloudantHome(String name) {
        return new File(CLOUDANT_HOME, name);
    }

    private static String getCloudantHome() {
        String dir = System.getProperty("user.dir");

        if (dir != null) {
            // Look in the directory tree recursively.
            File propfile = findFileRecursively(dir, CLOUDANT_INSTALL_FILE);
            return propfile != null ? propfile.getParent() : null;
        } else return null;
    }

    private static File findFileRecursively(String dir, String needle) {
        if (dir != null) {
            File base = new File(dir);
            File file = new File(base, needle);
            if (file.exists()) {
                return file;
            } else {
                return findFileRecursively(base.getParent(), needle);
            }
        } else return null;
    }

}
