/**
 * 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.hcatalog.templeton.tool;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

/**
 *  HDFS implementation of templeton storage.
 *
 *  This implementation assumes that all keys in key/value pairs are
 *  chosen such that they don't have any newlines in them.
 *
 */
public class HDFSStorage implements TempletonStorage {
    FileSystem fs = null;

    public String storage_root = null;

    public static final String JOB_PATH = "/jobs";
    public static final String JOB_TRACKINGPATH = "/created";
    public static final String OVERHEAD_PATH = "/overhead";

    private static final Log LOG = LogFactory.getLog(HDFSStorage.class);

    public void startCleanup(Configuration config) {
        try {
            HDFSCleanup.startInstance(config);
        } catch (Exception e) {
            LOG.warn("Cleanup instance didn't start.");
        }
    }

    @Override
    public void saveField(Type type, String id, String key, String val)
        throws NotFoundException {
        if (val == null) {
            return;
        }
        PrintWriter out = null;
        try {
            Path keyfile = new Path(getPath(type) + "/" + id + "/" + key);
            // This will replace the old value if there is one
            // Overwrite the existing file
            out = new PrintWriter(new OutputStreamWriter(fs.create(keyfile)));
            out.write(val);
        } catch (IOException e) {
            LOG.info("Couldn't write to " + getPath(type) + "/" + id + ": "
                + e.getMessage());
        } finally {
            try {
                out.flush();
                out.close();
            } catch (Exception e) {
                // fail
            }
        }
    }

    @Override
    public String getField(Type type, String id, String key) {
        BufferedReader in = null;
        try {
            in = new BufferedReader(new InputStreamReader(fs.open(new Path(getPath(type) + "/" +
                id + "/" + key))));
            String line = null;
            String val = "";
            while ((line = in.readLine()) != null) {
                if (!val.equals("")) {
                    val += "\n";
                }
                val += line;
            }
            return val;
        } catch (IOException e) {
            LOG.trace("Couldn't find " + getPath(type) + "/" + id + "/" + key
                + ": " + e.getMessage());
        } finally {
            try {
                in.close();
            } catch (Exception e) {
                // fail
            }
        }
        return null;
    }

    @Override
    public Map<String, String> getFields(Type type, String id) {
        HashMap<String, String> map = new HashMap<String, String>();
        BufferedReader in = null;
        try {
            for (FileStatus status : fs.listStatus(new Path(getPath(type) + "/" + id))) {
                in = new BufferedReader(new InputStreamReader(fs.open(status.getPath())));
                String line = null;
                String val = "";
                while ((line = in.readLine()) != null) {
                    if (!val.equals("")) {
                        val += "\n";
                    }
                    val += line;
                }
                map.put(status.getPath().getName(), val);
            }
        } catch (IOException e) {
            LOG.trace("Couldn't find " + getPath(type) + "/" + id);
        } finally {
            try {
                in.close();
            } catch (Exception e) {
                // fail
            }
        }
        return map;
    }

    @Override
    public boolean delete(Type type, String id) throws NotFoundException {
        try {
            fs.delete(new Path(getPath(type) + "/" + id), true);
        } catch (IOException e) {
            throw new NotFoundException("Node " + id + " was not found: " +
                e.getMessage());
        }
        return false;
    }

    @Override
    public List<String> getAll() {
        ArrayList<String> allNodes = new ArrayList<String>();
        for (Type type : Type.values()) {
            allNodes.addAll(getAllForType(type));
        }
        return allNodes;
    }

    @Override
    public List<String> getAllForType(Type type) {
        ArrayList<String> allNodes = new ArrayList<String>();
        try {
            for (FileStatus status : fs.listStatus(new Path(getPath(type)))) {
                allNodes.add(status.getPath().getName());
            }
            return null;
        } catch (Exception e) {
            LOG.trace("Couldn't find children for type " + type.toString());
        }
        return allNodes;
    }

    @Override
    public List<String> getAllForKey(String key, String value) {
        ArrayList<String> allNodes = new ArrayList<String>();
        try {
            for (Type type : Type.values()) {
                allNodes.addAll(getAllForTypeAndKey(type, key, value));
            }
        } catch (Exception e) {
            LOG.trace("Couldn't find children for key " + key + ": " +
                e.getMessage());
        }
        return allNodes;
    }

    @Override
    public List<String> getAllForTypeAndKey(Type type, String key, String value) {
        ArrayList<String> allNodes = new ArrayList<String>();
        HashMap<String, String> map = new HashMap<String, String>();
        try {
            for (FileStatus status :
                fs.listStatus(new Path(getPath(type)))) {
                map = (HashMap<String, String>)
                    getFields(type, status.getPath().getName());
                if (map.get(key).equals(value)) {
                    allNodes.add(status.getPath().getName());
                }
            }
        } catch (Exception e) {
            LOG.trace("Couldn't find children for key " + key + ": " +
                e.getMessage());
        }
        return allNodes;
    }

    @Override
    public void openStorage(Configuration config) throws IOException {
        storage_root = config.get(TempletonStorage.STORAGE_ROOT);
        if (fs == null) {
            fs = FileSystem.get(config);
        }
    }

    @Override
    public void closeStorage() throws IOException {
        // Nothing to do here
    }

    /**
     * Get the path to storage based on the type.
     * @param type
     */
    public String getPath(Type type) {
        return getPath(type, storage_root);
    }

    /**
     * Static method to get the path based on the type.
     *
     * @param type
     * @param root
     */
    public static String getPath(Type type, String root) {
        String typepath = root + OVERHEAD_PATH;
        switch (type) {
        case JOB:
            typepath = root + JOB_PATH;
            break;
        case JOBTRACKING:
            typepath = root + JOB_TRACKINGPATH;
            break;
        }
        return typepath;
    }
}
