<?php

class UserTableSeeder extends Seeder {

    public function run()
    {
        // Disable query logging to avoid memory exhaustion
        DB::disableQueryLog();

        $this->command->info('Users table seeding started...');

        // Initiates time
        $time_start = microtime(true);

        // Remove access privileges to users that haven't logged in in 1 year
        User::whereNull('last_login')
            ->orWhere('last_login', '<', DB::raw('DATE_SUB(NOW(), INTERVAL 1 YEAR)'))
            ->update(array(
                'has_access' => 0
            ));

        // Open file
        if($file = fopen('app/database/csv/users.csv', 'r'))
        {
            // Initialize count variables
            $read = 0;
            $added = 0;
            $updated = 0;
            $error = 0;

            // Read each row
            while($data = fgetcsv($file, 5000))
            {
                // Add read count
                $read++;

                try
                {
                    // Get row info
                    $ssn = trim($data[0]);
                    // $number = (NOT YET ADDED)
                    $first_name = strtoupper(trim($data[1]));
                    $surnames = strtoupper(trim($data[2]));
                    $email = strtolower(trim($data[3]));
                    $emp_number = strtolower(trim($data[4]));

                    if($email=="null" or $email=="")
                    {
                    	$email="email".rand()."@upr.edu";
//                     	print($email);
//                     	var_dump($data);exit();
                    }
                    if($emp_number=="null" or $emp_number=="")
                    {
                    	$emp_number="NO".rand(10000000,99999999);
//                     	print($emp_number);
//                     	var_dump($data);exit();
                    }
                    // Program unavailable.For the moment, I'm setting it to null, but it should eventually be the commented line below
                    // $program_id = trim($data[4]);
                    $program_id = NULL;

                    // To output info for debugging purposes
                    // $this->command->info(substr($ssn, -4));
                    // $this->command->info($first_name);
                    // $this->command->info($surnames);
                    // $this->command->info($email);
                    // $this->command->info($program_id);
                    // $this->command->info('---');

                    // If any required field is empty, raise an exception
                    if(!$ssn || !$first_name || !$surnames || !$email)
                    {
                        throw new Exception('NON-FATAL ERROR(line '.$read.'): Missing information, read \''.implode(",", $data).'\'');
                    }

                    // If program is empty, assign default
                    if(!$program_id)
                    {
                        $program_id = 999; // Default program id, see DB.
                    }

                    // If user exists by ssn
                    if(User::where('ssn', $ssn)->count())
                    {
                        DB::table('users')
                            ->where('ssn', ($ssn))
                            ->update(array(
                                'first_name' => $first_name,
                                'surnames' => $surnames,
                                'email' => $email,
                                'number' => $emp_number,
                                // 'program_id' => $program_id, //should change when I know how this info will be given
                                'has_access' => 1,
                                'updated_at' => date("Y-m-d H:i:s", time()),
                                )
                            );
                        $this->command->info('Updated (via ssn): '.$email.': '.$surnames.', '.$first_name);
                        $updated++;
                    }
                    // If user exists by employee number, update information and add to updated
                    elseif(User::where('number', $emp_number)->count())
                    {
                        DB::table('users')
                            ->where('number', ($emp_number))
                            ->update(array(
                                'ssn' => $ssn,
                                'email' => $email,
                                'first_name' => $first_name,
                                'surnames' => $surnames,
                                // 'program_id' => $program_id, //should change when I know how this info will be given
                                'has_access' => 1,
                                'updated_at' => date("Y-m-d H:i:s", time()),
                                )
                            );
                        $this->command->info('Updated (via name): '.$email.': '.$surnames.', '.$first_name);
                        $updated++;
                    }
                    // If user exists by email, update information and add to updated
                    elseif(User::where('email', $email)->count())
                    {
                        DB::table('users')
                            ->where('email', ($email))
                            ->update(array(
                                'ssn' => $ssn,
                                'first_name' => $first_name,
                                'surnames' => $surnames,
                                'number' => $emp_number,
                                // 'program_id' => $program_id, //should change when I know how this info will be given
                                'has_access' => 1,
                                'updated_at' => date("Y-m-d H:i:s", time()),
                                )
                            );
                        $this->command->info('Updated (via email): '.$email.': '.$surnames.', '.$first_name);
                        $updated++;
                    }
                    // Otherwise, create user and add to added
                    else
                    {
                        $user = User::create(array(
                            'ssn' => $ssn,
                            // 'number' => $number,
                            'first_name' => $first_name,
                            'surnames' => $surnames,
                            'email' => $email,
                            'number' => $emp_number,
                            'has_access' => 1,
                            'role' => 4,
                            // 'program_id' => $program_id, //should change when I know how this info will be given
                            )
                        );

                        DB::table('program_user')->insert(
                            array('program_id' => $program_id, 'user_id' => $user->id)
                        );

                        $this->command->info('Added '.$email.': '.$surnames.', '.$first_name);
                        $added++;
                    }
                }

                // If an exception is raised, show the message and add to error
                catch(Exception $e)
                {
                    $this->command->info($e->getMessage());
                    $error++;
                };
            }

            // Stop time
            $time_end = microtime(true);

            // Display results
            $this->command->info('------------------------------------------------------------');
            $this->command->info('Results on '.date('M d, Y, h:i:s a'));
            $this->command->info('- Runtime: '.(round($time_end - $time_start, 3)).' seconds');
            $this->command->info('- Read: '.$read);
            $this->command->info('- Updated (active): '.$updated);
            $this->command->info('- Added (new active): '.$added);
            $this->command->info('- Not updated (inactive): '.(User::count() - $updated - $added));
            $this->command->info('- Not added/updated (errors or missing information): '.($error));

            // Close file
            fclose($file);
        }
        // File cannot be opened, display error and exit
        else
        {
            $this->command->info('File '.$filename.' could not be opened. Make sure it is located in the app/database/csv directory of this project.');
        }
    }

}
