package com.iamberry.app.service;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.http.ParseException;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.iamberry.app.config.ImberryConfig;
import com.iamberry.app.core.entity.Machine;
import com.iamberry.app.core.entity.User;
import com.iamberry.app.face.MachineService;
import com.iamberry.app.tool.util.HttpUtility;

/**
 * MachineService
 *
 * @author Moon Cheng
 * @date 2016年3月23日 下午12:27:32
 */
@Service
public class MachineServiceImpl extends BaseService implements MachineService {

	private Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
	
	/**
	 * setMachine
	 * @author Moon Cheng
	 * @param machine
	 * @param token
	 * @return Machine Information
	 */
	@Transactional
	public Machine setMachine(Machine machine, String token, String ip) {
		User userInfo = validateUserToken(token);
		if (userInfo == null) {
			return null;
		}
		if (ip.indexOf(",") != -1) {
			ip = ip.split(",")[0];
		}
		logger.info("IP为:" + ip);

		String location = null;
		try {
			location = new JSONObject(
					HttpUtility.httpsGet(MessageFormat.format(ImberryConfig.SINA_IP_URL,ip)))
							.getString("city");
		} catch (ParseException | IOException | JSONException e) {
			e.printStackTrace();
		}
		machine.setLocation(location);

		machine.setOwner(userInfo.getId());
		Long machineId = machineMapper.isDevUserPairExist(machine.getMachine_mac(), userInfo.getId());
		machine.setCreated_on(new Date());
		if (machineId == null) {
			machineMapper.insertMachine(machine);
		} else {
			machine.setId(machineId);
			machineMapper.updateMachine(machine);
		}
		return machine;
	}

	/**
	 * updateMachineStatus
	 *
	 * @author Moon Cheng
	 * @param machineId
	 * @param status
	 * @param token
	 * @return
	 */
	public int updateMachineStatus(Long machineId, String status, String token) {
		User userInfo = validateUserToken(token);
		if (userInfo == null) {
			return -1;
		}
		return machineMapper.updateMachineStatus(status, machineId);
	}

	/**
	 * updateMachineLocation
	 *
	 * @author Moon Cheng
	 * @param machineId
	 * @param location
	 * @param token
	 * @return
	 */
	public int updateMachineLocation(Long machineId, String location, String token) {
		User userInfo = validateUserToken(token);
		if (userInfo == null) {
			return -1;
		}
		return machineMapper.updateMachineLocation(location, machineId);
	}

	/**
	 * 	按用户，查询所有机器
	 * @param owner
	 * @param token
	 * @return
	 */
	public List<Machine> searchMachineByOwner(Long owner, String token) {
		User userInfo = validateUserToken(token);
		if (userInfo == null) {
			return null;
		}
		List<Machine> machines = machineMapper.selectMachineByOwner(owner);
		return machines;
	}

	/**
	 * searchMachineById
	 *
	 * @author Moon Cheng
	 * @param machineId
	 * @param token
	 * @return
	 */
	public Machine searchMachineById(Long machineId, String token) {
		User userInfo = validateUserToken(token);
		if (userInfo == null) {
			return null;
		}
		Machine machine = machineMapper.selectMachineById(machineId);
		return machine;
	}

	/**
	 * updateStatus
	 *
	 * @param status
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public void updateStatus(String status) {
		// the method is expensive!
		Map<String, Object> map = new HashMap<>();
		try {
			map = mapper.readValue(status,new HashMap<String, Object>().getClass());
			
		} catch (IOException e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		for (Entry<String, Object> entry : map.entrySet()) {
			if (entry.getValue() instanceof String) {
				machineMapper.updateStatusByMac(entry.getKey(),  entry.getValue().equals("0") ? "online" : "offline");
			} else {
				machineMapper.updateStatusByMac(entry.getKey(),  (Integer)entry.getValue() == 0 ? "online" : "offline");
			}
		}
	}

	@Override
	public Long selectUserIDByDevId(String devId) {
		// TODO Auto-generated method stub
		return machineMapper.selectUserIDByDevId(devId);
	}
}
