/*
 * Copyright 2015 Open Networking Laboratory
 *
 * 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 org.onosproject.persistence.impl;

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Service;
import org.mapdb.DB;
import org.mapdb.DBMaker;
import org.onosproject.persistence.PersistenceService;
import org.onosproject.persistence.PersistentMapBuilder;
import org.onosproject.persistence.PersistentSetBuilder;
import org.slf4j.Logger;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;

import static org.slf4j.LoggerFactory.getLogger;

/**
 * Service that maintains local disk backed maps and sets.  This implementation automatically deletes empty structures
 * on shutdown.
 */
@Component(immediate = true)
@Service
public class PersistenceManager implements PersistenceService {

    private static final String DATABASE_PATH = "../data/localDB";

    private static final String ENCLOSING_FOLDER = "../data";

    static final String MAP_PREFIX = "map:";

    static final String SET_PREFIX = "set:";

    private final Logger log = getLogger(getClass());

    private DB localDB = null;

    private static final int FLUSH_FREQUENCY_MILLIS = 3000;

    private final Timer timer = new Timer();

    private final CommitTask commitTask = new CommitTask();

    @Activate
    public void activate() {
        Path dbPath = Paths.get(DATABASE_PATH);
        Path dbFolderPath = Paths.get(ENCLOSING_FOLDER);
        //Make sure the directory exists, if it does not, make it.
        if (!dbFolderPath.toFile().isDirectory()) {
            log.info("The specified folder location for the database did not exist and will be created.");
            try {
                Files.createDirectories(dbFolderPath);
            } catch (IOException e) {
                log.error("Could not create the required folder for the database.");
                throw new PersistenceException("Database folder could not be created.");
            }
        }
        //Notify if the database file does not exist.
        boolean dbFound = Files.exists(dbPath);
        if (!dbFound) {
            log.info("The database file could not be located, a new database will be constructed.");

        } else {
            log.info("A previous database file has been found.");
        }
        localDB = DBMaker.newFileDB(dbPath.toFile())
                .asyncWriteEnable()
                .closeOnJvmShutdown()
                .make();
        timer.schedule(commitTask, FLUSH_FREQUENCY_MILLIS, FLUSH_FREQUENCY_MILLIS);
        log.info("Started");
    }

    @Deactivate
    public void deactivate() {
        for (Map.Entry<String, Object> entry : localDB.getAll().entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
                //This is a map implementation to be handled as such
            if (value instanceof Map) {
                Map asMap = (Map) value;
                if (asMap.isEmpty()) {
                    //the map is empty and may be deleted
                    localDB.delete(key);
                }
                //This is a set implementation and can be handled as such
            } else if (value instanceof Set) {
                Set asSet = (Set) value;
                if (asSet.isEmpty()) {
                    //the set is empty and may be deleted
                    localDB.delete(key);
                }
            }
        }
        localDB.commit();
        localDB.close();
        log.info("Stopped");
    }

    public <K, V> PersistentMapBuilder<K, V> persistentMapBuilder() {
        return new DefaultPersistentMapBuilder<>(localDB);
    }

    public <E> PersistentSetBuilder<E> persistentSetBuilder() {
        return new DefaultPersistentSetBuilder<>(localDB);
    }

    private class CommitTask extends TimerTask {

        @Override
        public void run() {
            localDB.commit();
        }
    }
}