#coding=utf-8

namespace :gitlab do
  desc "sync gitlab's users which lost in last sync"
  task :add_gid => :environment do
    users = User.find_by_sql("select * from users where gid is null")
    s = Trustie::Gitlab::Sync.new
    g = Gitlab.client
    logger_i = Logger.new('./log/task_add_gid.log', 'daily')
    logger_e = Logger.new('./log/task_add_gid_error.log', 'daily')
    NAMESPACE_REGEX_STR = '(?:[a-zA-Z0-9_\.][a-zA-Z0-9_\-\.]*[a-zA-Z0-9_\-]|[a-zA-Z0-9_])'.freeze
    MAIL_REGEX_STR ='^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$'.freeze
    error_cnt=0
    success_cnt=0
    p "同步Gitlab用户开始..."
    users.each do |user|
      info="userid=#{user.id},mail=#{user.mail},login(username)=#{user.login},name=#{user.show_name}"
      # username不能有特殊字符,不能有保留字符,邮箱特殊字符(比如‘>’)导致search失败的,name不能为空串
      if !(user.login =~ /\A#{NAMESPACE_REGEX_STR}\Z/.freeze)
        logger_e.error("#{info},error=校验失败:username特殊字符")
        error_cnt+=1
        next
      elsif !(user.mail.downcase =~ /#{MAIL_REGEX_STR}/)
        logger_e.error("#{info},error=校验失败:邮箱特殊字符")
        error_cnt+=1
        next
      elsif user.show_name.lstrip.rstrip.blank?
        logger_e.error("#{info},error=校验失败:name不正常")
        error_cnt+=1
        next
      end
      begin
        us = g.get("/users?search=#{user.mail}")
        if us.blank?
          s.sync_user(user)
          logger_i.info("sync_remote_user:id=#{user.id},mail=#{user.mail}")
          success_cnt+=1
        else
          if Array === us
            us.each do |u|
              if u.email == user.mail
                user.gid = u.id
                # !爆炸方法抛出异常
                user.save!
                logger_i.info("sync_local_user:#{info}")
                success_cnt+=1
              end
            end
          end
        end
      rescue => e
        logger_e.error("#{info},error=#{e}")
        puts e
      end
    end
    p "同步Gitlab用户结束..."
    p "同步成功#{success_cnt},未完成#{error_cnt}"
  end

  task :sync_members => :environment do
    projects = Project.all
    s = Trustie::Gitlab::Sync.new
    projects.each do |project|
      puts project.id
      s.only_members(project.first)
    end
  end
end