/*
 * 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.jackrabbit.oak.segment.upgrade;

import static com.google.common.base.StandardSystemProperty.OS_NAME;
import static com.google.common.collect.Iterables.transform;
import static java.lang.String.format;
import static java.util.concurrent.TimeUnit.MINUTES;
import static org.apache.jackrabbit.oak.segment.SegmentVersion.V_12;
import static org.apache.jackrabbit.oak.segment.SegmentVersion.V_13;
import static org.apache.jackrabbit.oak.segment.data.SegmentData.newSegmentData;
import static org.apache.jackrabbit.oak.segment.file.FileStoreBuilder.fileStoreBuilder;
import static org.apache.jackrabbit.oak.segment.file.ManifestChecker.newManifestChecker;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.File;
import java.io.IOException;

import org.apache.jackrabbit.oak.segment.SegmentVersion;
import org.apache.jackrabbit.oak.segment.data.SegmentData;
import org.apache.jackrabbit.oak.segment.file.InvalidFileStoreVersionException;
import org.apache.jackrabbit.oak.segment.file.LocalManifestFile;
import org.apache.jackrabbit.oak.segment.spi.monitor.IOMonitorAdapter;
import org.apache.jackrabbit.oak.segment.file.tar.TarFiles;
import org.apache.jackrabbit.oak.segment.tool.Compact;
import org.jetbrains.annotations.NotNull;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

public class UpgradeIT {

    @Rule
    public TemporaryFolder fileStoreHome = new TemporaryFolder(new File("target"));

    /**
     * Launch a groovy script in an Oak 1.6. console to initialise the upgrade
     * source. See pom.xml for how these files are placed under target/upgrade-it.
     */
    @Before
    public void setup() throws IOException, InterruptedException {
        Process oakConsole = new ProcessBuilder(
                "java", "-jar", "oak-run.jar",
                "console", fileStoreHome.getRoot().getAbsolutePath(), "--read-write",
                ":load create16store.groovy")
                .directory(new File("target", "upgrade-it"))
                .start();
        assertTrue(
                "Timeout while creating the source repository",
                oakConsole.waitFor(2, MINUTES));
    }

    @Test
    public void openUpgradesStore() throws IOException, InvalidFileStoreVersionException {
        checkStoreVersion(1);
        fileStoreBuilder(fileStoreHome.getRoot())
                .build()
                .close();
        checkStoreVersion(2);
    }

    @Test
    public void openReadonlyDoesNotUpgradeStore() throws IOException, InvalidFileStoreVersionException {
        checkStoreVersion(1);
        fileStoreBuilder(fileStoreHome.getRoot())
                .buildReadOnly()
                .close();
        checkStoreVersion(1);
    }

    @Test
    public void offRCUpgradesSegments() throws IOException, InvalidFileStoreVersionException {
        checkSegmentVersion(V_12);
        checkStoreVersion(1);

        Compact.builder()
            .withPath(fileStoreHome.getRoot())
            .withMmap(true)
            .withOs(OS_NAME.value())
            .withForce(true)
            .build()
            .run();

        // Upgraded
        checkStoreVersion(2);
        checkSegmentVersion(V_13);
    }

    @Test
    public void offRCUpgradesRequiresForce() throws IOException, InvalidFileStoreVersionException {
        checkSegmentVersion(V_12);
        checkStoreVersion(1);

        Compact.builder()
            .withPath(fileStoreHome.getRoot())
            .withMmap(true)
            .withOs(OS_NAME.value())
            .withForce(false)
            .build()
            .run();

        // Not upgraded
        checkStoreVersion(1);
        checkSegmentVersion(V_12);
    }

    private void checkStoreVersion(int version) throws IOException, InvalidFileStoreVersionException {
        newManifestChecker(new LocalManifestFile(fileStoreHome.getRoot(), "manifest"),
                true, version, version).checkManifest();
    }

    private void checkSegmentVersion(@NotNull SegmentVersion version) throws IOException {
        try (TarFiles tarFiles = TarFiles.builder()
                .withDirectory(fileStoreHome.getRoot())
                .withTarRecovery((_1, _2, _3) -> fail("Unexpected recovery"))
                .withIOMonitor(new IOMonitorAdapter())
                .withReadOnly()
                .build()) {

            for (SegmentData segmentData : getSegments(tarFiles)) {
                SegmentVersion actualVersion = SegmentVersion.fromByte(segmentData.getVersion());
                assertEquals(
                        format("Segment version mismatch. Expected %s, found %s", version, actualVersion),
                        version, actualVersion);
            }
        }
    }

    private static Iterable<SegmentData> getSegments(@NotNull TarFiles tarFiles) {
        return transform(
                tarFiles.getSegmentIds(),
                uuid -> newSegmentData(tarFiles.readSegment(
                    uuid.getMostSignificantBits(),
                    uuid.getLeastSignificantBits())));
    }
}
