/*
 * Copyright 2015-present 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.osgi.service.component.ComponentContext;
import org.slf4j.Logger;

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

import static org.onosproject.security.AppGuard.checkPermission;
import static org.onosproject.security.AppPermission.Type.PERSISTENCE_WRITE;
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 = "localDB";

    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 Timer timer;

    private final CommitTask commitTask = new CommitTask();

    @Activate
    public void activate(ComponentContext context) {
        timer = new Timer();
        // bundle's persistent storage area directory
        File dbFolderPath = context.getBundleContext().getDataFile("");
        Path dbPath = dbFolderPath.toPath().resolve(DATABASE_PATH);
        log.debug("dbPath: {}", dbPath);

        //Make sure the directory exists, if it does not, make it.
        if (!dbFolderPath.isDirectory()) {
            log.info("The specified folder location for the database did not exist and will be created.");
            try {
                Files.createDirectories(dbFolderPath.toPath());
            } 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() {
        timer.cancel();
        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");
    }

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

    @Override
    public <E> PersistentSetBuilder<E> persistentSetBuilder() {
        checkPermission(PERSISTENCE_WRITE);
        return new DefaultPersistentSetBuilder<>(localDB);
    }

    private class CommitTask extends TimerTask {

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