/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * 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 com.android.internal.util;

import android.annotation.UnsupportedAppUsage;
import android.os.Build;

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

/**
 * @deprecated Use {@code AtomicFile} instead.  It would
 * be nice to update all existing uses of this to switch to AtomicFile, but since
 * their on-file semantics are slightly different that would run the risk of losing
 * data if at the point of the platform upgrade to the new code it would need to
 * roll back to the backup file.  This can be solved...  but is it worth it and
 * all of the testing needed to make sure it is correct?
 */
@Deprecated
public class JournaledFile {
    File mReal;
    File mTemp;
    boolean mWriting;

    @UnsupportedAppUsage
    public JournaledFile(File real, File temp) {
        mReal = real;
        mTemp = temp;
    }

    /** Returns the file for you to read.
     * @more
     * Prefers the real file.  If it doesn't exist, uses the temp one, and then copies
     * it to the real one.  If there is both a real file and a temp one, assumes that the
     * temp one isn't fully written and deletes it.
     */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    public File chooseForRead() {
        File result;
        if (mReal.exists()) {
            result = mReal;
            if (mTemp.exists()) {
                mTemp.delete();
            }
        } else if (mTemp.exists()) {
            result = mTemp;
            mTemp.renameTo(mReal);
        } else {
            return mReal;
        }
        return result;
    }

    /**
     * Returns a file for you to write.
     * @more
     * If a write is already happening, throws.  In other words, you must provide your
     * own locking.
     * <p>
     * Call {@link #commit} to commit the changes, or {@link #rollback} to forget the changes.
     */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    public File chooseForWrite() {
        if (mWriting) {
            throw new IllegalStateException("uncommitted write already in progress");
        }
        if (!mReal.exists()) {
            // If the real one doesn't exist, it's either because this is the first time
            // or because something went wrong while copying them.  In this case, we can't
            // trust anything that's in temp.  In order to have the chooseForRead code not
            // use the temporary one until it's fully written, create an empty file
            // for real, which will we'll shortly delete.
            try {
                mReal.createNewFile();
            } catch (IOException e) {
                // Ignore
            }
        }

        if (mTemp.exists()) {
            mTemp.delete();
        }
        mWriting = true;
        return mTemp;
    }

    /**
     * Commit changes.
     */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    public void commit() {
        if (!mWriting) {
            throw new IllegalStateException("no file to commit");
        }
        mWriting = false;
        mTemp.renameTo(mReal);
    }

    /**
     * Roll back changes.
     */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    public void rollback() {
        if (!mWriting) {
            throw new IllegalStateException("no file to roll back");
        }
        mWriting = false;
        mTemp.delete();
    }
}
