using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;
namespace CarManagerV3
{
///
/// Handles safe reading and writing of car data to files.
///
internal class SafeManager
{
///
/// The path of the txt file that contains recently opened file paths.
///
private static string recentPathsFile = Properties.Settings.Default.DataLocation + "\\recent_paths.txt";
///
/// Initializes a file at a specified path if it does not already exist.
///
/// The path of the file.
public static void InitializeFile(string path)
{
try
{
if (!File.Exists(@path))
{
using (StreamWriter writer = new StreamWriter(@path))
{
// Create the file, empty
//writer.WriteLine();
writer.Close();
}
}
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error initializing file: {ex.Message}");
}
}
///
/// Initializes a file and its parent folders at a specified path if they do not already exist.
///
/// The path of the file.
public static void initializeFileAndFolders(string path, bool folderOnly = false)
{
try
{
//string directory = Path.GetDirectoryName(path);
Console.WriteLine($"Initializing file and folders for path: {path}");
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
if(!folderOnly) InitializeFile(path);
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error initializing file and folders: {ex.Message}");
}
}
///
/// Ensures the directory exists.
///
/// The path.
public static void EnsureDirectoryExists(string path)
{
try
{
string directory = Path.GetDirectoryName(path);
if (directory != null && !Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error ensuring directory exists: {ex.Message}");
}
}
///
/// Reads cars from a specified file path.
///
/// The path.
///
/// A containing the cars read from the file.
///
public static List ReadCars(string path)
{
List cars = new List();
List failedLines = new List();
bool isLegacy = false;
try
{
using (StreamReader reader = new StreamReader(@path))
{
string line;
while ((line = reader.ReadLine()) != null)
{
// Process the line
if (line == "") continue;
if (Car.isLegacyCsvString(line))
{
if (!StateManager.askForMigration())
{
MessageBox.Show("The file you are trying to open is in an old format that is no longer supported. Please select a different file.", "Unsupported Format", MessageBoxButtons.OK, MessageBoxIcon.Error);
throw new LegacyException();
//Environment.Exit(0);
}
else
{
isLegacy = true;
}
}
Car tmp = Car.FromCsvString(line);
if (tmp == null)
{
failedLines.Add(line);
continue;
}
cars.Add(tmp);
}
reader.Close();
}
}
catch (LegacyException ex)
{
throw ex;
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error reading cars from file: {ex.Message}");
}
if (failedLines.Count > 0)
{
Console.Error.WriteLine($"Warning: {failedLines.Count} lines could not be parsed and were skipped.");
foreach (string failedLine in failedLines)
{
Console.Error.WriteLine($"Failed line: {failedLine}");
}
MessageBox.Show($"Warning: {failedLines.Count} lines in the file could not be parsed and were skipped. Check the console for details.", "Parsing Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
cars = StateManager.normalizeOrders(cars);
cars = cars.OrderBy(c => c.Order).ToList();
if (isLegacy)
{
SafeManager.SaveCars(path, cars);
}
return cars;
}
///
/// Saves the cars to a specified file path.
///
/// The path.
/// A containing all cars to save.
public static void SaveCars(string path, List cars)
{
try
{
using (StreamWriter writer = new StreamWriter(@path))
{
foreach (Car car in cars)
{
writer.WriteLine(car.ToCsvString());
}
writer.Close();
}
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error saving cars to file: {ex.Message}");
MessageBox.Show($"Error saving cars to file: {ex.Message}", "Save Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
///
/// Adds a file path to the recent paths list.
/// If a path is already in the list, it is moved to the top.
/// Otherwise, it is added to the top.
/// Keeps only the 5 most recent paths.
///
/// The path.
public static void AddRecentPath(string path)
{
List paths = new List();
try
{
paths = GetRecentPaths();
paths.Remove(path);
paths.Insert(0, path);
if (paths.Count > 5)
{
paths = paths.Take(5).ToList();
}
using (StreamWriter writer = new StreamWriter(recentPathsFile))
{
foreach (string p in paths)
{
writer.WriteLine(p);
}
writer.Close();
}
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error managing recent paths: {ex.Message}");
}
}
///
/// Gets the recently opened file paths.
///
///
/// A containing the recent file paths.
///
public static List GetRecentPaths()
{
List paths = new List();
try
{
recentPathsFile = Properties.Settings.Default.DataLocation + "\\recent_paths.txt";
initializeFileAndFolders(recentPathsFile);
if (File.Exists(recentPathsFile)) //TODO: Remove
{
using (StreamReader reader = new StreamReader(recentPathsFile))
{
string line;
while ((line = reader.ReadLine()) != null)
{
paths.Add(line);
}
reader.Close();
}
}
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error reading recent paths: {ex.Message}");
}
return paths;
}
///
/// Gets the folder of the most recently opened file.
///
///
/// The folder path of the most recently opened file, or the users documents folder if no recent files.
///
public static string getRecentFolder()
{
List recentPaths = GetRecentPaths();
if (recentPaths.Count > 0)
{
string recentFile = recentPaths[0];
if (File.Exists(recentFile))
{
return Path.GetDirectoryName(recentFile);
}
}
return Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
}
///
/// Clears the recently opened file paths list by deleting the recent paths file.
///
public static void ClearRecentPaths()
{
try
{
if (File.Exists(recentPathsFile))
{
File.Delete(recentPathsFile);
}
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error clearing recent paths: {ex.Message}");
}
}
}
}