module Api
  module V1
    class DeviceTestsController < ApplicationController
      skip_before_action :verify_authenticity_token

      # GET /api/v1/device_tests?mac=xxx
      # GET /api/v1/device_tests?sn=xxx
      def show
        if params[:mac].present?
          @device_test = DeviceTest.where(mac: params[:mac]).order("id DESC").first
        elsif params[:sn].present?
          @device_test = DeviceTest.where(sn: params[:sn]).order("id DESC").first
        end
        if @device_test
          render json: { code: 200, msg: "ok", id: @device_test.id, sn: @device_test.sn, mac: @device_test.mac, created_at: @device_test.created_at, updated_at: @device_test.updated_at, failed_items: @device_test.result}
        else
          render json: { code: 0, msg: "failed"}
        end
      end

      # POST /api/v1/device_tests
      def create
      	mac = params[:mac].to_s.strip
        sn = params[:sn].to_s.strip
        client_ip = request.remote_ip

        if mac.size != 12
          render plain: "failed:mac invalid" and return
        end

        if sn != 'SA' && sn != 'testtest' && sn.size != 8
          render plain: "failed:sn invalid" and return
        end

      	if params[:token].blank? || params[:log].blank? || params[:result].blank?
      		render plain: "failed:Missing required params" and return
        end

        # TODO: Remove after client app fixed it.
        log = params[:log]
        if params[:log].is_a?(ActionDispatch::Http::UploadedFile)
          log = params[:log].read
        end

        compute_token = Digest::MD5.hexdigest(sn + mac + log + params[:result] + "duckula")
        if compute_token != params[:token]
          render plain: "failed:Invalid request" and return
        end

        if sn != 'SA' and sn != 'testtest'
          if DeviceTest.where("sn=? and mac <> ?", sn, mac).exists?
            render plain: "failed:SN used." and return
          end
        end

        device_test = DeviceTest.order("id DESC").find_or_initialize_by(mac: mac)
        device_test.sn = sn
        device_test.app_version = params[:app_version].to_s

        device_test.ip = client_ip
        device_test.result = params[:result].to_i
        if device_test.new_record?
          device_test.vendor = params[:vendor].to_s == "" ? "N/A" : params[:vendor].to_s
        end

        test_type = 0
        if sn == 'SA'
          test_type = 0
        elsif sn.size == 8 && sn != 'testtest'
          test_type = 3
        end

        # Ignore 'testtest' sn db save.
        if sn == "testtest"
          render plain: "ok:sn:#{device_test.sn}" and return
        end

        device_test.device_test_histories.build(test_type: test_type, mac: mac, sn: sn, log: log, ip: client_ip, result: params[:result].to_i, app_version: params[:app_version].to_s, vendor: params[:vendor].to_s)

      	if device_test.save
			    render plain: "ok:sn:#{device_test.sn}" and return
      	else
      		render plain: "failed:#{device_test.errors.full_messages.join(";")}" and return
      	end
      end

      # POST /api/v1/device_test_items
      # params[:mac], length 12
      # params[:test_name], string: datetime_set; screen_fix
      # params[:result], integer, 0 true, 1 false
      # params[:log], string
      # params[:app_version], string
      # params[:token], string: md5(mac + test_name + result + log + xxxxxxxx)
      #
      # curl -X POST --data "mac=64CFD9C529A4&test_name=datetime_set&result=0&token=05e7afe319c3ea516dc66c90f6e0e74c"  http://localhost:3000/api/v1/device_test_items
      def log_test_item
        mac = params[:mac].to_s.strip
        test_name = params[:test_name].to_s.strip
        result = params[:result].to_s.strip
        log = params[:log].to_s.strip
        token = params[:token].to_s.strip

        client_ip = request.remote_ip
        if mac.size != 12
          render plain: "failed:mac invalid" and return
        end

        if test_name.blank? || test_name.size > 32
          render plain: "failed:test_name invalid" and return
        end

        if result.blank?
          render plain: "failed:result invalid" and return
        end

        if token.size != 32
          render plain: "failed:token invalid" and return
        end

        compute_token = Digest::MD5.hexdigest(mac + test_name + result + log + "duckula")
        if compute_token != token
          render plain: "failed:Invalid request" and return
        end

        device_test = DeviceTest.where("mac=?", mac).order("id DESC").first
        if device_test.blank?
          render plain: "failed:Not found device" and return
        end
        test_type = 0
        if test_name == 'datetime_set'
          device_test.datetime_set = (result.to_i == 0 ? 1 : 0)
          test_type = 1
        elsif test_name == 'screen_fix'
          device_test.screen_fixed = (result.to_i == 0 ? 1 : 0)
          test_type = 2
        else
          render plain: "failed:Invalid test_name" and return
        end

        device_test.app_version = params[:app_version].to_s
        device_test.ip = client_ip
        device_test.device_test_histories.build(test_type: test_type, mac: mac, sn: device_test.sn, log: log, ip: client_ip, result: result.to_i, app_version: params[:app_version].to_s)
        if device_test.save
			    render plain: "ok:sn:#{device_test.sn}" and return
      	else
      		render plain: "failed:#{device_test.errors.full_messages.join(";")}" and return
      	end

      end

      # POST /api/v1/log_aging_test
      # params[:mac], length 12
      # params[:app_version]
      # params[:ip]
      # params[:unamea]
      # params[:test_duration], integer, unit:minutes
      # params[:uboot_md5]
      # params[:token]
      # curl -X POST --data "mac=3403DE754F80&app_version=v0.1.2&ip=192.168.8.25&unamea=ubuntu&test_duration=60&token=6452ed0a9df2e42f46b39bbdbb4e2524"  http://localhost:3000/api/v1/log_aging_test
      def log_aging_test
        mac = params[:mac].to_s.strip.upcase
        app_version = params[:app_version].to_s.strip
        lan_ip = params[:ip].to_s.strip
        uname_info = params[:unamea].to_s.strip
        uname_info = URI.decode(uname_info)
        test_duration = params[:test_duration].to_s.strip
        uboot_md5 = params[:uboot_md5].to_s.strip
        token = params[:token].to_s.strip

        if mac.size != 12 || app_version.blank? || lan_ip.blank? || uname_info.blank? || test_duration.blank? || token.blank?
          render plain: "failed:Params invalid" and return
        end

        compute_token = Digest::SHA256.hexdigest(mac + app_version + lan_ip + uname_info + test_duration + uboot_md5 + "duckula")
        if compute_token != token
          render plain: "failed:Invalid request" and return
        end

        device_test = DeviceTest.where("mac=?", mac.downcase).order("id DESC").first
        if device_test.blank?
          render plain: "failed:Not found test device" and return
        end

        device_aging_test = DeviceAgingTest.new
        device_aging_test.mac = mac
        device_aging_test.app_version = app_version
        device_aging_test.uname_info = uname_info
        device_aging_test.test_duration = test_duration.to_i
        device_aging_test.uboot_md5 = uboot_md5
        device_aging_test.lan_ip = lan_ip
        device_aging_test.ip = request.remote_ip
        begin
          DeviceTest.transaction do
            device_aging_test.save!
            device_test.update_columns(aging_test_count: device_test.aging_test_count + 1)
          end
        rescue ActiveRecord::RecordInvalid
          render plain: "failed:Saved failed" and return
        end
        render plain: "ok:Saved"
      end

  	end
  end
end
