/*
 * 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.rya.mongodb.dao;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;

import org.apache.commons.codec.binary.Hex;
import org.apache.rya.api.persist.RyaDAOException;
import org.apache.rya.mongodb.StatefulMongoDBRdfConfiguration;
import org.openrdf.model.Namespace;

import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;

import info.aduna.iteration.CloseableIteration;

public class SimpleMongoDBNamespaceManager implements MongoDBNamespaceManager {

    public class NamespaceImplementation implements Namespace {

        private final String namespace;
        private final String prefix;

        public NamespaceImplementation(final String namespace, final String prefix) {
            this.namespace = namespace;
            this.prefix = prefix;
        }

        @Override
        public int compareTo(final Namespace o) {
            if (!namespace.equalsIgnoreCase(o.getName())) {
                return namespace.compareTo(o.getName());
            }
            if (!prefix.equalsIgnoreCase(o.getPrefix())) {
                return prefix.compareTo(o.getPrefix());
            }
            return 0;
        }

        @Override
        public String getName() {
            return namespace;
        }

        @Override
        public String getPrefix() {
            return prefix;
        }

    }

    public class MongoCursorIteration implements
    CloseableIteration<Namespace, RyaDAOException> {
        private final DBCursor cursor;

        public MongoCursorIteration(final DBCursor cursor2) {
            this.cursor = cursor2;
        }

        @Override
        public boolean hasNext() throws RyaDAOException {
            return cursor.hasNext();
        }

        @Override
        public Namespace next() throws RyaDAOException {
            final DBObject ns = cursor.next();
            final Map values = ns.toMap();
            final String namespace = (String) values.get(NAMESPACE);
            final String prefix = (String) values.get(PREFIX);

            final Namespace temp =  new NamespaceImplementation(namespace, prefix);
            return temp;
        }

        @Override
        public void remove() throws RyaDAOException {
            next();
        }

        @Override
        public void close() throws RyaDAOException {
            cursor.close();
        }

    }

    private static final String ID = "_id";
    private static final String PREFIX = "prefix";
    private static final String NAMESPACE = "namespace";
    private StatefulMongoDBRdfConfiguration conf;
    private final DBCollection nsColl;


    public SimpleMongoDBNamespaceManager(final DBCollection nameSpaceCollection) {
        nsColl = nameSpaceCollection;
    }

    @Override
    public void createIndices(final DBCollection coll){
        coll.createIndex(PREFIX);
        coll.createIndex(NAMESPACE);
    }

    @Override
    public void setConf(final StatefulMongoDBRdfConfiguration conf) {
        this.conf = conf;
    }

    @Override
    public StatefulMongoDBRdfConfiguration getConf() {
        return conf;
    }

    @Override
    public void addNamespace(final String prefix, final String namespace)
            throws RyaDAOException {
        final String id = prefix;
        byte[] bytes = id.getBytes(StandardCharsets.UTF_8);
        try {
            final MessageDigest digest = MessageDigest.getInstance("SHA-1");
            bytes = digest.digest(bytes);
        } catch (final NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        final BasicDBObject doc = new BasicDBObject(ID, new String(Hex.encodeHex(bytes)))
                .append(PREFIX, prefix)
                .append(NAMESPACE, namespace);
        nsColl.insert(doc);

    }

    @Override
    public String getNamespace(final String prefix) throws RyaDAOException {
        final DBObject query = new BasicDBObject().append(PREFIX, prefix);
        final DBCursor cursor = nsColl.find(query);
        String nameSpace = prefix;
        while (cursor.hasNext()){
            final DBObject obj = cursor.next();
            nameSpace = (String) obj.toMap().get(NAMESPACE);
        }
        return nameSpace;
    }

    @Override
    public void removeNamespace(final String prefix) throws RyaDAOException {
        final DBObject query = new BasicDBObject().append(PREFIX, prefix);
        nsColl.remove(query);
    }

    @Override
    public CloseableIteration<? extends Namespace, RyaDAOException> iterateNamespace()
            throws RyaDAOException {
        final DBObject query = new BasicDBObject();
        final DBCursor cursor = nsColl.find(query);
        return new MongoCursorIteration(cursor);
    }

}
