//-
// Copyright 2018 The proptest developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(dead_code)]

use std::fs;
use std::io::{self, BufRead, Read, Seek, Write};
use std::path::Path;
use std::string::String;
use std::vec::Vec;

use crate::test_runner::{TestCaseError, TestCaseResult, Seed};

const SENTINEL: &'static str = "proptest-forkfile";

/// A "replay" of a `TestRunner` invocation.
///
/// The replay mechanism is used to support forking. When a child process
/// exits, the parent can read the replay to reproduce the state the child had;
/// similarly, if a child crashes, a new one can be started and given a replay
/// which steps it one complication past the input that caused the crash.
///
/// The replay system is tightly coupled to the `TestRunner` itself. It does
/// not carry enough information to be used in different builds of the same
/// application, or even two different runs of the test process since changes
/// to the persistence file will perturb the replay.
///
/// `Replay` has a special string format for being stored in files. It starts
/// with a line just containing the text in `SENTINEL`, then 16 lines
/// containing the values of `seed`, then an unterminated line consisting of
/// `+`, `-`, and `!` characters to indicate test case passes/failures/rejects,
/// `.` to indicate termination of the test run, or ` ` as a dummy "I'm alive"
/// signal. This format makes it easy for the child process to blindly append
/// to the file without having to worry about the possibility of appends being
/// non-atomic.
#[derive(Clone, Debug)]
pub(crate) struct Replay {
    /// The seed of the RNG used to start running the test cases.
    pub(crate) seed: Seed,
    /// A log of whether certain test cases passed or failed. The runner will
    /// assume the same results occur without actually running the test cases.
    pub(crate) steps: Vec<TestCaseResult>,
}

impl Replay {
    /// If `other` is longer than `self`, add the extra elements to `self`.
    pub fn merge(&mut self, other: &Replay) {
        if other.steps.len() > self.steps.len() {
            let sl = self.steps.len();
            self.steps.extend_from_slice(&other.steps[sl..]);
        }
    }
}

/// Result of loading a replay file.
#[derive(Clone, Debug)]
pub(crate) enum ReplayFileStatus {
    /// The file is valid and represents a currently-in-progress test.
    InProgress(Replay),
    /// The file is valid, but indicates that all testing has completed.
    Terminated(Replay),
    /// The file is not parsable.
    Corrupt,
}

/// Open the file in the usual read+append+create mode.
pub(crate) fn open_file(path: impl AsRef<Path>) -> io::Result<fs::File> {
    fs::OpenOptions::new()
        .read(true)
        .append(true)
        .create(true)
        .truncate(false)
        .open(path)
}

fn step_to_char(step: &TestCaseResult) -> char {
    match *step {
        Ok(_) => '+',
        Err(TestCaseError::Reject(_)) => '!',
        Err(TestCaseError::Fail(_)) => '-',
    }
}

/// Append the given step to the given output.
pub(crate) fn append(mut file: impl Write, step: &TestCaseResult)
              -> io::Result<()> {
    write!(file, "{}", step_to_char(step))
}

/// Append a no-op step to the given output.
pub(crate) fn ping(mut file: impl Write) -> io::Result<()> {
    write!(file, " ")
}

/// Append a termination mark to the given output.
pub(crate) fn terminate(mut file: impl Write) -> io::Result<()> {
    write!(file, ".")
}

impl Replay {
    /// Write the full state of this `Replay` to the given output.
    pub fn init_file(&self, mut file: impl Write) -> io::Result<()> {
        writeln!(file, "{}", SENTINEL)?;
        writeln!(file, "{}", self.seed.to_persistence())?;

        let mut step_data = Vec::<u8>::new();
        for step in &self.steps {
            step_data.push(step_to_char(step) as u8);
        }

        file.write_all(&step_data)?;

        Ok(())
    }

    /// Mark the replay as complete in the file.
    pub fn complete(mut file: impl Write) -> io::Result<()> {
        write!(file, ".")
    }

    /// Parse a `Replay` out of the given file.
    ///
    /// The reader is implicitly seeked to the beginning before reading.
    pub fn parse_from(mut file: impl Read + Seek)
                      -> io::Result<ReplayFileStatus> {
        file.seek(io::SeekFrom::Start(0))?;

        let mut reader = io::BufReader::new(&mut file);
        let mut line = String::new();

        // Ensure it starts with the sentinel. We do this since we rely on a
        // named temporary file which could be in a location where another
        // actor could replace it with, eg, a symlink to a location they don't
        // control but we do. By rejecting a read from a file missing the
        // sentinel, and not doing any writes if we can't read the file, we
        // won't risk overwriting another file since the prospective attacker
        // would need to be able to change the file to start with the sentinel
        // themselves.
        //
        // There are still some possible symlink attacks that can work by
        // tricking us into reading, but those are non-destructive things like
        // interfering with a FIFO or Unix socket.
        reader.read_line(&mut line)?;
        if SENTINEL != line.trim() {
            return Ok(ReplayFileStatus::Corrupt);
        }

        line.clear();
        reader.read_line(&mut line)?;
        let seed = match Seed::from_persistence(&line) {
            Some(seed) => seed,
            None => return Ok(ReplayFileStatus::Corrupt),
        };

        line.clear();
        reader.read_line(&mut line)?;

        let mut steps = Vec::new();
        for ch in line.chars() {
            match ch {
                '+' => steps.push(Ok(())),
                '-' => steps.push(Err(TestCaseError::fail(
                    "failed in other process"))),
                '!' => steps.push(Err(TestCaseError::reject(
                    "rejected in other process"))),
                '.' => return Ok(ReplayFileStatus::Terminated(
                    Replay { seed, steps })),
                ' ' => (),
                _ => return Ok(ReplayFileStatus::Corrupt),
            }
        }

        Ok(ReplayFileStatus::InProgress(Replay { seed, steps }))
    }
}
