<?php

class CourseTableSeeder extends Seeder {

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

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

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

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

            // Read each row
            while($data = fgetcsv($file, 5000, "|")) // se cambio delimitador para evitar problemas con nombres separados del apellido por coma
            {
                // Add read count
                $read++;
                // $this->command->info(print_r($data));

                try
                {
                    // Get row info
                    $name = $data[6];
                    $code = trim(substr($data[0], 0, 4));
                    $number = trim(substr($data[0], 4, 4));
                    $section = trim(substr($data[0], 8, 3));
                    $user_id = User::select('id')->where('ssn', trim($data[14]))->first();
                    $semester_id = Semester::select('id')->where('code', strtoupper(trim($data[2])))->first();
                    $program_code = trim($data[7]);

                    // If any row is empty, raise an exception
                    if($name=='' || $code=='' || $number=='' || $section=='' || trim($data[14])=='' || trim($data[2])=='')
                    {
                        throw new Exception('NON-FATAL ERROR(line '.$read.'): Missing information, read \''.implode(",", $data).'\'');
                    }

                    // Fetch semester. If it doesn't exist, abort script
                    if(!$semester_id['id'])
                    {
                        $this->command->info('FATAL ERROR(line '.$read.'): Semester not found in the database.');
                        exit();
                    }
                    else
                    {
                        $semester_id = $semester_id['id'];
                    }

                    // Fetch program. If it doesn't exist, set default program
                    $preexisting_course = Course::select('program_id')->where('code', $code)->where('number', $number)->first();
                    $program_id = 999;
                    if($preexisting_course)
                    {
                        $program_id = Program::find($preexisting_course->program_id)->id;
                    }
                    elseif(Program::select('id')->where('code', $program_code)->first())
                    {
                        $program_id = Program::select('id')->where('code', $program_code)->first()->id;
                    }

                    // Fetch user. If it doesn't exist, set default user
                    if(!$user_id && !$user_id['id'])
                    {
                        $user_id = 60; // Id for default user. Check DB for user with ssn 000000000.
                    }
                    else
                    {
                        $user_id = $user_id['id'];
                    }

                    // Check if course exists
                    $course = Course::where('code', $code)->where('number', $number)->where('section', $section)->where('semester_id', $semester_id)->first();

                    //If it does, update information and add to updated
                    if($course)
                    {
                        //print_r($course);
                        DB::table('courses')
                            ->where('id', $course->id)
                            ->update(
                                array(
                                    'name' => $name,
                                    'code' => $code,
                                    'number' => $number,
                                    'section' => $section,
                                    'program_id' => $program_id,
                                    'user_id' => $user_id,
                                    'updated_at' => date("Y-m-d H:i:s", time())
                                )
                            );
                        $this->command->info('Updated '.$code.$number.$section.': '.$name);
                        $updated++;

                    }
                    // Otherwise, add course and add to added
                    else
                    {
                        Course::create(array(
                            'name' => $name,
                            'code' => $code,
                            'number' => $number,
                            'section' => $section,
                            'program_id' => $program_id,
                            'user_id' => $user_id,
                            'semester_id' => $semester_id
                            )
                        );
                        $this->command->info('Added '.$code.$number.$section.': '.$name);
                        $added++;
                    }
                }

                // If an exception is raised, show the message and add to error
                catch(Exception $e)
                {
                    $this->command->info($e->getMessage().'[RECORD '.$read.']'.$e->getLine());
                    $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): '.(Course::count() - $updated - $added));
            $this->command->info('- Not added/updated (errors or missing information): '.($error));
            $this->command->info('- Note: A negative number in the results may mean there are duplicate values.');



            // 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.');
        }
    }

}