/*
 * 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");
    public static final File FILTER_DDOC_PATH = getFileRelativeToCloudantHome("tests/dat/filterdesigndoc.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;
    }

}
