#!/usr/bin/env ruby

# Warning this is a job announcement!
# Run it/Read it if you are interested.
# Lack of comments and robust input handling are intentional.

class Company
   attr_accessor :name, :location, :web_site, :description
   attr_accessor :available_jobs

   def initialize(name = nil, location = nil, web_site = nil)
     self.name = name
     self.location = location
     self.web_site = web_site
     self.available_jobs = Array.new
   end

   def ask_for_interview?(job_applicant)
     available_jobs.each do |ajob|
       return true if ajob.meets_requirements?(job_applicant)
     end
     false
   end

   def describe
     puts "Company  : #{name}"
     puts "Location : #{location}"
     puts "Web site : #{web_site}"
     puts "","Brief description :"
     puts description, ""
   end

   def announce_job_availability(good_match, not_so_good_match)
     return if available_jobs.empty?
     describe
     puts "Available jobs:"
     available_jobs.each_with_index do |job, idx|
       puts "", "#{idx + 1} ) #{job.name}", job.description, ""
     end

     job_applicant = ask_for_job_applicant_information
     return if job_applicant.nil?

     if ask_for_interview?( job_applicant )
       puts good_match
     else
       puts not_so_good_match
     end
   end

   def ask_for_job_applicant_information
     job_applicant = nil
     puts "Would you like to apply for a job? Y/N"
     res = gets.chomp
     if res =~ /Y/i
       msg = "Great!  Please follow the prompts to input your profile"
       msg<< " to see if there if a job matches."
       puts msg, ""
       job_applicant = JobApplicant.new_from_interactive_shell
     else
       puts "Well thanks for reading/running the program!  Good Bye!"
     end
     job_applicant
   end

end

class Job
   attr_accessor :name, :description, :requirements, :threshold
   def initialize(name = nil, description = nil,
                  threshold = 100, requirements = [] )
     self.name = name
     self.description = description
     self.requirements = requirements
     self.threshold = threshold
   end

   def meets_requirements?(job_applicant)
     points = 0
     requirements.each do |req|
       points += req.check_requirement(job_applicant)
     end
     points >= threshold
   end

end

class JobApplicant
   attr_accessor :name, :resume, :location
   attr_accessor :spoken_languages, :computer_languages_skills
   def initialize
     self.spoken_languages = Array.new
     self.computer_languages_skills = Array.new
   end

   def JobApplicant.new_from_interactive_shell
     applicant = JobApplicant.new
     puts "What is your name?"
     applicant.name = gets.chomp
     puts "Where do you live? (City, Country)"
     applicant.location = gets.chomp
     note = " [One entry per line.  Press CTRL-D to stop input] "
     puts "What languages do you speak?", note
     applicant.spoken_languages = readlines.map { |d| d.chomp }
     cq1 = "What computer languages are you proficient in?"
     cq2 = "And what other computer skills do you have?"
     puts cq1, cq2, note
     applicant.computer_languages_skills = readlines.map {|d| d.chomp }
     puts ""
     applicant
   end

end

class Requirement

   def initialize(points = 1, &proc)
     @points = points
     if proc
       @requirement_calc = proc
     else
       @requirement_calc = Proc.new { |x| true }
     end
   end

   def check_requirement(job_applicant)
     points = 0
     if @requirement_calc.call(job_applicant)
       points = @points
     end
     points
   end

end



ubit = Company.new("Ubit", "Tokyo, Japan", "http://ubit.com")
ubit.description =<<EOF
Ubit is a Japanese company focusing on mobile phone services and
content aggregation both in Japan and abroad.
EOF

developer = Job.new("Software Developer")
developer.description =<<EOF
Become knowledgeable in the inner workings of our
product platform and work as a team with other developers to implement
new features and improve our current capabilities.  Ideally, you are
willing to work under dynamic conditions and communicate well with
others.
EOF


loose_find = lambda do |data, reg_match|
   data.find { |v| v =~ match }
end

reqs = Array.new
reqs<< Requirement.new(25) do |ja|
   ja.spoken_languages.include?("English")
end

reqs<< Requirement.new(25) do |ja|
   ja.spoken_languages.include?("Japanese")
end

reqs<< Requirement.new(5) do |ja|
   sub = ["English", "Japanese"]
   (ja.spoken_languages - sub).size > 0
end

reqs<< Requirement.new(50) do |ja|
   ja.computer_languages_skills.include?("Ruby")
end

reqs<< Requirement.new(25) do |ja|
   ja.computer_languages_skills.include?("Databases")
end

reqs<< Requirement.new(10) do |ja|
   ja.computer_languages_skills.include?("Mobile Technologies")
end

reqs<< Requirement.new(5) do |ja|
   ja.computer_languages_skills.include?("*NIX")
end

reqs<< Requirement.new(5) do |ja|
   (ja.computer_languages_skills - ["Ruby", "Database"]).size > 0
end

reqs<< Requirement.new(25) do |ja|
   ja.location =~ /Japan/i
end

developer.requirements = reqs
developer.threshold = 125

ubit.available_jobs<< developer

good_match =<<EOF
Your profile looks promising!
If you are interested in working with us,
please send your resume to Zev Blut at rubyzbibd / ubit.com
EOF

nsgm =<<EOF
Sorry, at the moment we are in need of people who meet our specific
needs.  But if you feel that you can meet them then go ahead and send
your resume to Zev Blut at rubyzbibd / ubit.com
EOF

ubit.announce_job_availability(good_match,nsgm)