/*
 * Copyright 2017 HugeGraph Authors
 *
 * 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 com.baidu.hugegraph.computer.core.store.file.hgkvfile;

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

import org.apache.commons.lang3.StringUtils;

import com.baidu.hugegraph.computer.core.common.exception.ComputerException;
import com.baidu.hugegraph.computer.core.io.IOFactory;
import com.baidu.hugegraph.computer.core.io.RandomAccessInput;
import com.baidu.hugegraph.computer.core.io.RandomAccessOutput;
import com.baidu.hugegraph.util.E;

public class HgkvFileImpl extends AbstractHgkvFile {

    public HgkvFileImpl(String path) {
        super(path);
    }

    public static HgkvFile create(String path) throws IOException {
        File file = new File(path);
        E.checkArgument(!file.exists(),
                        "Can't create HgkvFile because the " +
                        "file already exists: '%s'", file.getPath());
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        file.createNewFile();

        return new HgkvFileImpl(path);
    }

    public static HgkvFile open(String path) throws IOException {
        E.checkArgumentNotNull(path, "Parameter path can't be null");
        return open(new File(path));
    }

    public static HgkvFile open(File file) throws IOException {
        E.checkArgumentNotNull(file, "Parameter file can't be null");
        E.checkArgument(file.exists(),
                        "Failed to open path because the " +
                        "file does not exists: '%s'", file.getPath());
        E.checkArgument(file.isFile(),
                        "Failed to open path because it's not a file: '%s'",
                        file.getPath());

        HgkvFileImpl hgkvFile = new HgkvFileImpl(file.getPath());
        hgkvFile.readFooter();
        return hgkvFile;
    }

    private static String version(short majorVersion, short minorVersion) {
        return StringUtils.join(majorVersion, ".", minorVersion);
    }

    @Override
    public RandomAccessOutput output() throws IOException {
        return IOFactory.createFileOutput(new File(this.path));
    }

    @Override
    public void close() throws IOException {
        // pass
    }

    private void readFooter() throws IOException {
        File file = new File(this.path);
        // The footerLength occupied 4 bytes, versionLength 2 * 2 bytes
        long versionOffset = file.length() - Short.BYTES * 2 - Integer.BYTES;

        try (RandomAccessInput input = IOFactory.createFileInput(file)) {
            input.seek(versionOffset);
            // Read version
            short majorVersion = input.readShort();
            short minorVersion = input.readShort();
            String version = version(majorVersion, minorVersion);
            // Read footerLength
            int footerLength = input.readFixedInt();
            switch (version) {
                case "1.0":
                    this.readFooterV1d0(input, file.length() - footerLength);
                    break;
                default:
                    throw new ComputerException("Illegal HgkvFile version '%s'",
                                                version);
            }
        }
    }

    private void readFooterV1d0(RandomAccessInput input, long footerBegin)
                                throws IOException {
        input.seek(footerBegin);

        // Read magic
        String magic = new String(input.readBytes(MAGIC.length()));
        E.checkArgument(MAGIC.equals(magic),
                        "Failed to read footer, illegal hgvk-file magic in " +
                        "file: '%s'", this.path);
        this.magic = magic;
        // Read numEntries
        this.numEntries = input.readLong();
        // Read numSubEntries
        this.numSubEntries = input.readLong();
        // Read dataBlock length
        this.dataBlockSize = input.readLong();
        // Read indexBlock length
        this.indexBlockSize = input.readLong();
        // Read max key and min key
        long maxKeyOffset = input.readLong();
        long minKeyOffset = input.readLong();
        // Read version
        short majorVersion = input.readShort();
        short minorVersion = input.readShort();
        this.version = version(majorVersion, minorVersion);

        if (this.numEntries > 0) {
            // Read max key
            input.seek(maxKeyOffset);
            int maxKeyLength = input.readFixedInt();
            this.max = input.readBytes(maxKeyLength);
            // Read min Key
            input.seek(minKeyOffset);
            int minKeyLength = input.readFixedInt();
            this.min = input.readBytes(minKeyLength);
        }
    }
}
