/**
 * 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.falcon.extensions;

import junit.framework.Assert;
import org.apache.falcon.FalconException;
import org.apache.falcon.cluster.util.MiniHdfsClusterUtil;
import org.apache.falcon.entity.ClusterHelper;
import org.apache.falcon.entity.EntityUtil;
import org.apache.falcon.entity.parser.EntityParserFactory;
import org.apache.falcon.entity.parser.ProcessEntityParser;
import org.apache.falcon.entity.store.ConfigurationStore;
import org.apache.falcon.entity.v0.Entity;
import org.apache.falcon.entity.v0.EntityType;
import org.apache.falcon.entity.v0.SchemaHelper;
import org.apache.falcon.entity.v0.cluster.Cluster;
import org.apache.falcon.entity.v0.process.EngineType;
import org.apache.falcon.entity.v0.process.PolicyType;
import org.apache.falcon.entity.v0.process.Process;
import org.apache.falcon.extensions.mirroring.hdfs.HdfsMirroringExtension;
import org.apache.falcon.extensions.mirroring.hdfs.HdfsMirroringExtensionProperties;
import org.apache.falcon.extensions.mirroring.hdfsSnapshot.HdfsSnapshotMirrorProperties;
import org.apache.falcon.extensions.mirroring.hdfsSnapshot.HdfsSnapshotMirroringExtension;
import org.apache.falcon.extensions.store.AbstractTestExtensionStore;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.permission.FsAction;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.hdfs.DistributedFileSystem;
import org.apache.hadoop.hdfs.MiniDFSCluster;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.util.List;
import java.util.Properties;

/**
 * Tests for Extension.
 */
public class ExtensionTest extends AbstractTestExtensionStore {
    private static final String PRIMARY_CLUSTER_XML = "/primary-cluster-0.1.xml";
    private static final String BACKUP_CLUSTER_XML = "/backup-cluster-0.1.xml";
    private static final String JOB_NAME = "hdfs-mirroring-monthly";
    private static final String JOB_CLUSTER_NAME = "primaryCluster";
    private static final String VALIDITY_START = "2016-01-02T00:00Z";
    private static final String VALIDITY_END = "2018-01-02T00:00Z";
    private static final String FREQUENCY = "days(1)";
    private static final String SOURCEDIR = "/users/source/file1";
    private static final String SOURCE_CLUSTER = "primaryCluster";
    private static final String TARGETDIR = "/users/target/file1";
    private static final String TARGET_CLUSTER = "backupCluster";
    private static final String NN_URI = "hdfs://localhost:54314";
    private static final String RETENTION_POLICY = "delete";
    private static final String RETENTION_AGE = "mins(5)";
    private static final String RETENTION_NUM = "7";
    private static final String TARGET_KERBEROS_PRINCIPAL = "nn/backup@REALM";

    private Extension extension;
    private MiniDFSCluster miniDFSCluster;
    private DistributedFileSystem miniDfs;
    private File baseDir;

    private static Properties getCommonProperties() {
        Properties properties = new Properties();
        properties.setProperty(ExtensionProperties.JOB_NAME.getName(),
                JOB_NAME);
        properties.setProperty(ExtensionProperties.CLUSTER_NAME.getName(),
                JOB_CLUSTER_NAME);
        properties.setProperty(ExtensionProperties.VALIDITY_START.getName(),
                VALIDITY_START);
        properties.setProperty(ExtensionProperties.VALIDITY_END.getName(),
                VALIDITY_END);
        properties.setProperty(ExtensionProperties.FREQUENCY.getName(),
                FREQUENCY);
        return properties;
    }

    private static InputStream getHdfsConfigStream() throws IOException {
        Properties properties = getCommonProperties();
        properties.setProperty(HdfsMirroringExtensionProperties.SOURCE_DIR.getName(),
                SOURCEDIR);
        properties.setProperty(HdfsMirroringExtensionProperties.SOURCE_CLUSTER.getName(),
                SOURCE_CLUSTER);
        properties.setProperty(HdfsMirroringExtensionProperties.TARGET_DIR.getName(),
                TARGETDIR);
        properties.setProperty(HdfsMirroringExtensionProperties.TARGET_CLUSTER.getName(),
                TARGET_CLUSTER);

        return getConfigStream(properties, "target/hdfsconfig.properties");
    }

    private static InputStream getHdfsSnapshotExtensionConfigStream() throws IOException {
        Properties properties = getCommonProperties();
        properties.setProperty(HdfsSnapshotMirrorProperties.SOURCE_SNAPSHOT_DIR.getName(),
                SOURCEDIR);
        properties.setProperty(HdfsSnapshotMirrorProperties.SOURCE_CLUSTER.getName(),
                SOURCE_CLUSTER);
        properties.setProperty(HdfsSnapshotMirrorProperties.SOURCE_SNAPSHOT_RETENTION_POLICY.getName(),
                RETENTION_POLICY);
        properties.setProperty(HdfsSnapshotMirrorProperties.SOURCE_SNAPSHOT_RETENTION_AGE_LIMIT.getName(),
                RETENTION_AGE);
        properties.setProperty(HdfsSnapshotMirrorProperties.SOURCE_SNAPSHOT_RETENTION_NUMBER.getName(),
                RETENTION_NUM);
        properties.setProperty(HdfsSnapshotMirrorProperties.SOURCE_NN.getName(),
                NN_URI);

        properties.setProperty(HdfsSnapshotMirrorProperties.TARGET_SNAPSHOT_DIR.getName(),
                TARGETDIR);
        properties.setProperty(HdfsSnapshotMirrorProperties.TARGET_CLUSTER.getName(),
                TARGET_CLUSTER);
        properties.setProperty(HdfsSnapshotMirrorProperties.TARGET_SNAPSHOT_RETENTION_POLICY.getName(),
                RETENTION_POLICY);
        properties.setProperty(HdfsSnapshotMirrorProperties.TARGET_SNAPSHOT_RETENTION_AGE_LIMIT.getName(),
                RETENTION_AGE);
        properties.setProperty(HdfsSnapshotMirrorProperties.TARGET_SNAPSHOT_RETENTION_NUMBER.getName(),
                RETENTION_NUM);
        properties.setProperty(HdfsSnapshotMirrorProperties.TARGET_NN.getName(),
                NN_URI);
        properties.setProperty(HdfsSnapshotMirrorProperties.MAX_MAPS.getName(),
                "5");
        properties.setProperty(HdfsSnapshotMirrorProperties.MAP_BANDWIDTH_IN_MB.getName(),
                "100");
        properties.setProperty(HdfsSnapshotMirrorProperties.TDE_ENCRYPTION_ENABLED.getName(),
                "false");

        return getConfigStream(properties, "target/HdfsSnapshotMirror.properties");
    }

    private static InputStream getConfigStream(Properties properties, String pathName) throws IOException {
        File file = new File(pathName);
        file.delete();
        OutputStream outputStream = new FileOutputStream(pathName);
        properties.store(outputStream, null);
        outputStream.close();
        return new FileInputStream(pathName);
    }

    @BeforeClass
    public void init() throws Exception {
        initExtensionStore();
        extension = new Extension();
        baseDir = Files.createTempDirectory("test_extensions_hdfs").toFile().getAbsoluteFile();
        miniDFSCluster = MiniHdfsClusterUtil.initMiniDfs(MiniHdfsClusterUtil.EXTENSION_TEST_PORT, baseDir);
        initClusters();
        miniDfs = miniDFSCluster.getFileSystem();
        miniDfs.mkdirs(new Path(SOURCEDIR), new FsPermission(FsAction.ALL, FsAction.ALL, FsAction.ALL));
        miniDfs.mkdirs(new Path(TARGETDIR), new FsPermission(FsAction.ALL, FsAction.ALL, FsAction.ALL));
    }

    private void initClusters() throws Exception {
        InputStream inputStream = getClass().getResourceAsStream(PRIMARY_CLUSTER_XML);
        Cluster primaryCluster = (Cluster) EntityType.CLUSTER.getUnmarshaller().unmarshal(inputStream);
        ConfigurationStore.get().publish(EntityType.CLUSTER, primaryCluster);

        inputStream = getClass().getResourceAsStream(BACKUP_CLUSTER_XML);
        Cluster backupCluster = (Cluster) EntityType.CLUSTER.getUnmarshaller().unmarshal(inputStream);
        ConfigurationStore.get().publish(EntityType.CLUSTER, backupCluster);
    }

    @Test
    public void testGetExtensionEntitiesForHdfsMirroring() throws FalconException, IOException {
        ProcessEntityParser parser = (ProcessEntityParser) EntityParserFactory.getParser(EntityType.PROCESS);

        List<Entity> entities = extension.getEntities(new HdfsMirroringExtension().getName(), getHdfsConfigStream());
        if (entities == null || entities.isEmpty()) {
            Assert.fail("Entities returned cannot be null or empty");
        }

        Assert.assertEquals(1, entities.size());
        Entity entity = entities.get(0);


        Assert.assertEquals(EntityType.PROCESS, entity.getEntityType());
        parser.parse(new ByteArrayInputStream(entity.toString().getBytes()));

        // Validate
        Process processEntity = (Process) entity;
        Assert.assertEquals(JOB_NAME, processEntity.getName());
        org.apache.falcon.entity.v0.process.Cluster jobCluster = processEntity.getClusters().
                getClusters().get(0);
        Assert.assertEquals(JOB_CLUSTER_NAME, jobCluster.getName());
        Assert.assertEquals(VALIDITY_START, SchemaHelper.formatDateUTC(jobCluster.getValidity().getStart()));
        Assert.assertEquals(VALIDITY_END, SchemaHelper.formatDateUTC(jobCluster.getValidity().getEnd()));

        Assert.assertEquals(FREQUENCY, processEntity.getFrequency().toString());
        Assert.assertEquals("UTC", processEntity.getTimezone().getID());

        Assert.assertEquals(EngineType.OOZIE, processEntity.getWorkflow().getEngine());
        Assert.assertEquals(extensionStorePath + "/hdfs-mirroring/libs",
                processEntity.getWorkflow().getLib());
        Assert.assertEquals(extensionStorePath
                        + "/hdfs-mirroring/resources/runtime/hdfs-mirroring-workflow.xml",
                processEntity.getWorkflow().getPath());

        Properties props = EntityUtil.getEntityProperties(processEntity);

        String srcClusterEndPoint = ClusterHelper.getReadOnlyStorageUrl(ClusterHelper.getCluster(SOURCE_CLUSTER));
        Assert.assertEquals(srcClusterEndPoint + SOURCEDIR, props.getProperty("sourceDir"));
        Assert.assertEquals(SOURCE_CLUSTER, props.getProperty("sourceCluster"));
        String tgtClusterEndPoint = ClusterHelper.getStorageUrl(ClusterHelper.getCluster(TARGET_CLUSTER));
        Assert.assertEquals(tgtClusterEndPoint + TARGETDIR, props.getProperty("targetDir"));
        Assert.assertEquals(TARGET_CLUSTER, props.getProperty("targetCluster"));

        //retry
        Assert.assertEquals(3, processEntity.getRetry().getAttempts());
        Assert.assertEquals(PolicyType.PERIODIC, processEntity.getRetry().getPolicy());
        Assert.assertEquals("minutes(30)", processEntity.getRetry().getDelay().toString());
    }

    @Test(expectedExceptions = FalconException.class,
            expectedExceptionsMessageRegExp = "Missing extension property: jobClusterName")
    public void testGetExtensionEntitiesForHdfsMirroringMissingMandatoryProperties()
        throws FalconException, IOException {
        Properties props = new Properties();
        props.load(getHdfsConfigStream());
        props.remove(ExtensionProperties.CLUSTER_NAME.getName());

        extension.getEntities(new HdfsMirroringExtension().getName(),
                getConfigStream(props, "target/HdfsMirroringMissingMandatory.properties"));
    }

    @Test
    public void testGetExtensionEntitiesForHdfsSnapshotMirroring() throws Exception {
        ProcessEntityParser parser = (ProcessEntityParser) EntityParserFactory.getParser(EntityType.PROCESS);

        miniDfs.allowSnapshot(new Path(SOURCEDIR));
        miniDfs.allowSnapshot(new Path(TARGETDIR));

        List<Entity> entities = extension.getEntities(new HdfsSnapshotMirroringExtension().getName(),
                getHdfsSnapshotExtensionConfigStream());
        if (entities == null || entities.isEmpty()) {
            Assert.fail("Entities returned cannot be null or empty");
        }

        Assert.assertEquals(1, entities.size());
        Entity entity = entities.get(0);
        Assert.assertEquals(EntityType.PROCESS, entity.getEntityType());
        parser.parse(new ByteArrayInputStream(entity.toString().getBytes()));

        // Validate
        Process processEntity = (Process) entity;
        Assert.assertEquals(JOB_NAME, processEntity.getName());
        org.apache.falcon.entity.v0.process.Cluster jobCluster = processEntity.getClusters().
                getClusters().get(0);
        Assert.assertEquals(JOB_CLUSTER_NAME, jobCluster.getName());
        Assert.assertEquals(VALIDITY_START, SchemaHelper.formatDateUTC(jobCluster.getValidity().getStart()));
        Assert.assertEquals(VALIDITY_END, SchemaHelper.formatDateUTC(jobCluster.getValidity().getEnd()));

        Assert.assertEquals(FREQUENCY, processEntity.getFrequency().toString());
        Assert.assertEquals("UTC", processEntity.getTimezone().getID());

        Assert.assertEquals(EngineType.OOZIE, processEntity.getWorkflow().getEngine());
        Assert.assertEquals(extensionStorePath + "/hdfs-snapshot-mirroring/libs",
                processEntity.getWorkflow().getLib());
        Assert.assertEquals(extensionStorePath
                        + "/hdfs-snapshot-mirroring/resources/runtime/hdfs-snapshot-mirroring-workflow.xml",
                processEntity.getWorkflow().getPath());

        Properties props = EntityUtil.getEntityProperties(processEntity);

        Assert.assertEquals(SOURCEDIR, props.getProperty("sourceSnapshotDir"));
        Assert.assertEquals(SOURCE_CLUSTER, props.getProperty("sourceCluster"));
        Assert.assertEquals(TARGETDIR, props.getProperty("targetSnapshotDir"));
        Assert.assertEquals(TARGET_CLUSTER, props.getProperty("targetCluster"));
        Assert.assertEquals(JOB_NAME, props.getProperty("snapshotJobName"));
        Assert.assertEquals(HdfsSnapshotMirroringExtension.EMPTY_KERBEROS_PRINCIPAL,
                props.getProperty("sourceNNKerberosPrincipal"));
        Assert.assertEquals(TARGET_KERBEROS_PRINCIPAL, props.getProperty("targetNNKerberosPrincipal"));

        //retry
        Assert.assertEquals(3, processEntity.getRetry().getAttempts());
        Assert.assertEquals(PolicyType.PERIODIC, processEntity.getRetry().getPolicy());
        Assert.assertEquals("minutes(30)", processEntity.getRetry().getDelay().toString());
    }


    @Test(dependsOnMethods = "testGetExtensionEntitiesForHdfsSnapshotMirroring",
            expectedExceptions = FalconException.class,
            expectedExceptionsMessageRegExp = "sourceSnapshotDir /users/source/file1 does not allow snapshots.")
    public void testHdfsSnapshotMirroringNonSnapshotableDir() throws Exception {
        miniDfs.disallowSnapshot(new Path(SOURCEDIR));

        List<Entity> entities = extension.getEntities(new HdfsSnapshotMirroringExtension().getName(),
                getHdfsSnapshotExtensionConfigStream());
        if (entities == null || entities.isEmpty()) {
            Assert.fail("Entities returned cannot be null or empty");
        }
    }

    @Test(expectedExceptions = FalconException.class,
            expectedExceptionsMessageRegExp = "Missing extension property: sourceCluster")
    public void testGetExtensionEntitiesForHdfsSnapshotMirroringMissingProperties()
        throws FalconException, IOException {
        Properties props = new Properties();
        props.load(getHdfsSnapshotExtensionConfigStream());
        props.remove(HdfsSnapshotMirrorProperties.SOURCE_CLUSTER.getName());
        extension.getEntities(new HdfsSnapshotMirroringExtension().getName(),
                getConfigStream(props, "target/HdfsSnapshotMirroringMissing.propertes"));
    }

    @Test(dependsOnMethods = "testHdfsSnapshotMirroringNonSnapshotableDir",
            expectedExceptions = FalconException.class,
            expectedExceptionsMessageRegExp = "sourceSnapshotDir /users/source/file1 does not exist.")
    public void testHdfsSnapshotMirroringNonExistingDir() throws Exception {
        if (miniDfs.exists(new Path(SOURCEDIR))) {
            miniDfs.delete(new Path(SOURCEDIR), true);
        }

        List<Entity> entities = extension.getEntities(new HdfsSnapshotMirroringExtension().getName(),
                getHdfsSnapshotExtensionConfigStream());
        if (entities == null || entities.isEmpty()) {
            Assert.fail("Entities returned cannot be null or empty");
        }
    }

    @AfterClass
    public void cleanup() throws Exception {
        MiniHdfsClusterUtil.cleanupDfs(miniDFSCluster, baseDir);
    }
}
