package com.atlassian.bitbucket.mesh.migration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Optional;

import static java.util.Objects.requireNonNull;
import static java.util.Optional.empty;
import static java.util.Optional.of;

public class DefaultMigrationStateManager implements MigrationStateManager {

    private static final Path PATH_MIGRATION = Paths.get("migration");

    private static final Logger log = LoggerFactory.getLogger(DefaultMigrationStateManager.class);

    private final Path hierarchiesDataDir;

    public DefaultMigrationStateManager(Path hierarchiesDataDir) {
        this.hierarchiesDataDir = hierarchiesDataDir;
    }

    @Nonnull
    @Override
    public HierarchyMigrationState createForHierarchy(@Nonnull String hierarchyId, int partition) throws IOException {
        return new DefaultHierarchyMigrationState(hierarchyId, getMigrationDir(hierarchyId), partition);
    }

    @Nonnull
    @Override
    public Optional<HierarchyMigrationState> getForHierarchy(@Nonnull String hierarchyId) {
        Path migrationDir = getMigrationDir(requireNonNull(hierarchyId, "hierarchyId"));
        try {
            return of(new DefaultHierarchyMigrationState(hierarchyId, migrationDir));
        } catch (FileNotFoundException | NoSuchFileException e) {
            //The details file does not exist, which means that we're not actively migrating the repository
        } catch (IOException e) {
            log.warn("Cannot open migration details file for hierarchy {}", hierarchyId, e);
        } catch (NumberFormatException e) {
            log.warn("Migration details file for hierarchy {} is invalid", hierarchyId);
        }
        return empty();
    }

    private Path getMigrationDir(String hierarchyId) {
        requireNonNull(hierarchyId, "hierarchyId");

        return hierarchiesDataDir
                .resolve(hierarchyId.substring(0, 2))
                .resolve(hierarchyId.substring(2))
                .resolve(PATH_MIGRATION);
    }
}
