package org.maachang.util;

import java.io.IOException;
import java.io.Serializable;

import org.maachang.util.FileUtil;

/**
 * シリアライズ可能な8byteシーケンスID管理.
 * 
 * @version 2008/10/28
 * @author masahito suzuki
 * @since MaachangBase 1.08
 */
public class SerializeSeqLong implements Serializable {
    private static final long serialVersionUID = -8207393046789510364L;
    
    /**
     * シーケンスID.
     */
    private long sequence ;
    
    /**
     * 最終保存時刻.
     */
    private long lastSaveTime = -1L ;
    
    /**
     * コンストラクタ.
     */
    public SerializeSeqLong() {
        sequence = 1L ;
    }
    
    /**
     * コンストラクタ.
     * @param id 開始位置を示すシーケンス番号を設定します.
     */
    public SerializeSeqLong( long id ) {
        if( id <= 0L ) {
            id = 1L ;
        }
        sequence = id ;
    }
    
    /**
     * オブジェクトローディング.
     * @param name 対象のファイル名を設定します.
     * @return SequenceLong ロードされたオブジェクトが返されます.
     * @exception Exception 例外.
     */
    public static final SerializeSeqLong load( String name ) throws Exception {
        if( name == null || ( name = name.trim() ).length() <= 0 ) {
            throw new IllegalArgumentException( "引数は不正です" ) ;
        }
        if( FileUtil.isFileExists( name ) == false ) {
            throw new IllegalArgumentException( "指定ファイル名("+name+")の内容は存在しません" ) ;
        }
        Object o = FileUtil.decodeSerializable( name ) ;
        if( o == null || ( o instanceof SerializeSeqLong ) == false ) {
            throw new IOException( "指定ファイル名[" + name + "]のオブジェクト内容は不正です" ) ;
        }
        return ( SerializeSeqLong )o ;
    }
    
    /**
     * オブジェクト保存.
     * @param name 対象のファイル名を設定します.
     * @exception Exception 例外.
     */
    public synchronized void save( String name ) throws Exception {
        if( name == null || ( name = name.trim() ).length() <= 0 ) {
            throw new IllegalArgumentException( "引数は不正です" ) ;
        }
        lastSaveTime = System.currentTimeMillis() ;
        FileUtil.encodeSerializable( name,this ) ;
    }
    
    /**
     * 最終保存時間を取得.
     * @return long 最終保存時間が返されます.
     */
    public synchronized long getLastSaveTime() {
        return lastSaveTime ;
    }
    
    /**
     * シーケンスIDを発行.
     * @return long シーケンスIDが発行されます.
     */
    public synchronized long getId() {
        long ret = sequence ;
        if( sequence <= Long.MAX_VALUE ) {
            sequence = 0L ;
        }
        else {
            sequence += 1L ;
        }
        return ret ;
    }
}
