<commit_before>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
using UserManagementApplication.Common.Exceptions;
using UserManagementApplication.Data.DataEntities;
using UserManagementApplication.Data.Providers;

namespace UserManagementApplication.Data.StorageProviders
{
    public class XMLStorageProvider : IStorageProvider
    {
        protected List<User> UserCache = new List<User>();
        private int _newUserId = 0;

        public string XmlFile { get; private set; }

        public XMLStorageProvider()
            : this("userData.xml") { }

        public XMLStorageProvider(string fileName)
        {
            if (!File.Exists(fileName))
            {
                File.Create(fileName);
            }

            XmlFile = fileName;
            reloadCache();
        }

        public IList<User> GetUsers()
        {
            return UserCache;
        }

        public User AddUser(User user)
        {
            user.UserId = _newUserId++;

            checkUserExistence(user);

            UserCache.Add(user);

            appendSerializedUser(user);
            InvalidateCache();


            return user;
        }

        public User UpdateUser(User user)
        {
            var userToUpdate = UserCache.Find(item => item.UserId == user.UserId);

            userToUpdate.Username  = user.Username;
            userToUpdate.Password  = <PASSWORD>;
            userToUpdate.FirstName = user.FirstName;
            userToUpdate.LastName  = user.LastName;
            userToUpdate.Birthdate = user.Birthdate;
            userToUpdate.RoleType  = user.RoleType;

            InvalidateCache();

            return user;
        }

        public User GetUserByUsername(string username)
        {
            return UserCache.Find(item => item.Username == username);
        }

        public void DeleteUser(User user)
        {
            var userToRemove = UserCache.Find(item => item.UserId == user.UserId);

            UserCache.Remove(userToRemove);

            InvalidateCache();
        }

        protected void InvalidateCache()
        {
            reloadCache();
        }

        private void reloadCache()
        {
            //throw new NotImplementedException();
        }

        private void appendSerializedUser(User user)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(User));
            
            using (StreamWriter streamWriter = new StreamWriter(XmlFile, true))
            {
                using (XmlWriter writer = XmlWriter.Create(streamWriter))
                {
                    serializer.Serialize(writer, user);
                }
            }
        }

        private void checkUserExistence(User user)
        {
            var userMatch = GetUserByUsername(user.Username);<commit_msg>xml storage provider add serializer<commit_after>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
using UserManagementApplication.Common.Exceptions;
using UserManagementApplication.Data.DataEntities;
using UserManagementApplication.Data.Providers;

namespace UserManagementApplication.Data.StorageProviders
{
    public class XMLStorageProvider : IStorageProvider
    {
        protected List<User> UserCache = new List<User>();
        private int _newUserId = 0;

        public string XmlFile { get; private set; }

        public XMLStorageProvider()
            : this("userData.xml") { }

        public XMLStorageProvider(string fileName)
        {
            XmlFile = fileName;

            if (!File.Exists(XmlFile))
            {
                using (var file = File.Create(XmlFile))
                {

                }
                
            }
            else
            {
                reloadCache();
            }
        }

        public IList<User> GetUsers()
        {
            return UserCache;
        }

        public User AddUser(User user)
        {
            user.UserId = _newUserId++;

            checkUserExistence(user);

            UserCache.Add(user);

            InvalidateCache();

            return user;
        }

        public User UpdateUser(User user)
        {
            var userToUpdate = UserCache.Find(item => item.UserId == user.UserId);

            userToUpdate.Username  = user.Username;
            userToUpdate.Password  = <PASSWORD>;
            userToUpdate.FirstName = user.FirstName;
            userToUpdate.LastName  = user.LastName;
            userToUpdate.Birthdate = user.Birthdate;
            userToUpdate.RoleType  = user.RoleType;

            InvalidateCache();

            return user;
        }

        public User GetUserByUsername(string username)
        {
            return UserCache.Find(item => item.Username == username);
        }

        public void DeleteUser(User user)
        {
            var userToRemove = UserCache.Find(item => item.UserId == user.UserId);

            UserCache.Remove(userToRemove);

            InvalidateCache();
        }

        protected void InvalidateCache()
        {
            flushUserCacheToDisk();
            reloadCache();
        }

        private void reloadCache()
        {
            UserCache.Clear();

            XmlSerializer serializer = new XmlSerializer(typeof(List<User>));

            using (StreamReader streamReader = new StreamReader(XmlFile))
            {
                using (XmlReader reader = XmlReader.Create(streamReader))
                {
                    UserCache = serializer.Deserialize(reader) as List<User>;
                }
            }
        }

        //TODO: optimize this so we don't do a big write
        private void flushUserCacheToDisk()
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<User>));
            
            using (StreamWriter streamWriter = new StreamWriter(XmlFile, true))
            {
                using (XmlWriter writer = XmlWriter.Create(streamWriter))
                {
                    serializer.Serialize(writer, UserCache);
                }
            }
        }

        private void checkUserExistence(User user)
        {
            var userMatch = GetUserByUsername(user.Username);
{'fraction_non_alphanumeric': 0.08254313695010104, 'fraction_numerical': 0.000310896937665164, 'mean_word_length': 1.7285835453774385, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 3}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6721346', 'n_tokens_mistral': 1622, 'n_tokens_neox': 1563, 'n_words': 335}