#
# Cookbook Name:: hadoop
# Library:: Helper
#
# Copyright 2013, whitestar
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

module Helper
  USERS_V1 = {
    :hadoop => {:name => 'hadoop', :uid => 10001},
    :hdfs   => {:name => 'hdfs',   :uid => 10002},
    :mapred => {:name => 'mapred', :uid => 10003}
  }
  USERS_V2 = USERS_V1.merge(
    {:yarn => {:name => 'yarn', :uid => 10004}}
  )

  LIMITS_FILES_V1 = [
    'hdfs.conf',
    'mapreduce.conf'
  ]
  LIMITS_FILES_V2 = LIMITS_FILES_V1 + ['yarn.conf']


  def parse_version_number(version)
    if /^(\d+)\.(\d+)\.(\d+)\.?(\d*)[-\w]*$/ =~ version then
      major_version = $1
      middle_version = "#{$1}.#{$2}"
    else
      Chef::Application.fatal!("Invalid Hadoop version: #{version}")
    end
  
    return [version, major_version, middle_version]
  end


  def parse_cdh_version_number(version)
    if /^(\d+)(u|\.)(\d+)\.?(\d*)$/ =~ version then
      major_version = $1
      middle_version = "#{$1}.#{$3}"
    else
      Chef::Application.fatal!("Invalid Hadoop version: #{version}")
    end
  
    return [version, major_version, middle_version]
  end


  def parse_hdp_version_number(version)
    if /^(\d+)\.(\d+)\.(\d+)\.?(\d*)$/ =~ version then
      major_version = $1
      middle_version = "#{$1}.#{$2}"
    else
      Chef::Application.fatal!("Invalid Hadoop version: #{version}")
    end
  
    return [version, major_version, middle_version]
  end


  def get_equivalent_apache_hadoop_version_of(distribution, middle_version)
    case distribution
      when 'cdh'
        case middle_version
          when '4.2', '4.3' then return '2.0'
          when '3.5', '3.6' then return '1.1'
        end
      when 'hdp'
        case middle_version
          when '2.0' then return '2.0'
          when '1.3' then return '1.2'
          when '1.2' then return '1.1'
        end
    end
  end


  def get_users(major_version)
    case major_version
      when '1'
        return USERS_V1
      when '2'
        return USERS_V2
    end
  end


  def get_limits_files(major_version)
    case major_version
      when '1'
        return LIMITS_FILES_V1
      when '2'
        return LIMITS_FILES_V2
    end
  end


  def setup_directories(major_version)
    users = get_users(major_version)

    active_vol_nums = 0
    node['grid']['max_vol_nums'].to_i.times {|vol_num|
      target_vol_dir = "#{node['grid']['vol_root']}/#{vol_num}"
    
      if vol_num == 0 || FileTest::directory?(target_vol_dir) then
        directory "#{target_vol_dir}/var" do
          owner 'root'
          group 'root'
          mode '0755'
          action :create
          recursive true
        end
    
        %w{lib log}.each {|dir|
          directory "#{target_vol_dir}/var/#{dir}" do
            owner 'root'
            group users[:hadoop][:name]
            mode '0775'
            action :create
            recursive true
          end
        }
    
        if major_version == '2' then
          directory "#{target_vol_dir}/var/log/yarn" do
            owner users[:yarn][:name]
            group users[:hadoop][:name]
            mode '0755'
            action :create
            recursive true
          end
    
          directory "#{target_vol_dir}/var/log/yarn/nm" do
            owner users[:yarn][:name]
            group users[:hadoop][:name]
            mode '0755'
            action :create
            recursive true
          end
    
          directory "#{target_vol_dir}/var/log/yarn/nm/local" do
            owner users[:yarn][:name]
            group users[:hadoop][:name]
            mode '0755'
            action :create
            recursive true
          end
        end
    
        directory "#{target_vol_dir}/tmp" do
          owner 'root'
          group 'root'
          mode '1777'
          action :create
          recursive true
        end
    
        if major_version == '2' then
          directory "#{target_vol_dir}/mapred/tmp" do
            owner 'root'
            group 'root'
            mode '1777'
            action :create
            recursive true
          end
        end
    
        if vol_num == 0 then
          directory "#{target_vol_dir}/var/run" do
            owner 'root'
            group users[:hadoop][:name]
            mode '0775'
            action :create
            recursive true
          end
    
          directory "#{target_vol_dir}/var/log/hdfs" do
            owner users[:hdfs][:name]
            group users[:hdfs][:name]
            mode '0755'
            action :create
            recursive true
          end
        end
      else
        break
      end
      active_vol_nums = vol_num + 1
    }
    
    return active_vol_nums
  end


  def conf_template(conf_dir, middle_version, conf_files, tpl_vars)
    source_dir = (middle_version == '2.0') \
      ? "etc-#{middle_version}/hadoop" \
      : "conf-#{middle_version}"
  
    conf_files.each {|conf_file|
      template "#{conf_dir}/#{conf_file}" do
        source "#{source_dir}/#{conf_file}"
        owner 'root'
        group 'root'
        mode '0644'
        variables(tpl_vars)
      end
    }
  end


  def get_jsvc_pkg_name
    case node[:platform_family]
      when 'debian'
        return 'jsvc'
      when 'rhel'
        return 'jakarta-commons-daemon-jsvc'
    end
  end
end
