import React from "react";
import { shallow, configure } from "enzyme";
import Adapter from "enzyme-adapter-react-16";
configure({ adapter: new Adapter() });
import _ from "lodash";

import { Controls, mapStateToProps } from "../../app/src/components/Controls";


describe("Controls", () => {
	const tags = {
		cfg_PID_FlowSP: { value: 0 },
		cfg_PID_FluidLevelSP: { value: 0 },
		cfg_PID_TubingPressureSP: { value: 0 },
		cfg_PID_ManualSP: { value: 0 },
		Device_Status_INT: { value: 0 },
		sts_PID_Control: { value: 5 }
	};

	it("should render loading if no tags prop", () => {
		const wrapper = shallow(<Controls tags={undefined}/>);
		expect(wrapper.find(".loading-notags")).toHaveLength(1);
	});

	it("should render loading if no Device_Status_INT in tags", () => {
		const wrapper = shallow(<Controls tags={_.omit(tags, "Device_Status_INT")} />);
		expect(wrapper.find(".loading-nostatus")).toHaveLength(1);
	});

	it("should render controls div", () => {
		const wrapper = shallow(<Controls tags={tags} />);
		expect(wrapper.find(".controls")).toHaveLength(1);
	});

	describe("control parameters", () => {
		let writeTag;
		beforeEach(() => {
			writeTag = jest.fn((tag, val) => {
				return {tag, val};
			});
		});

		it("should run the writeTag function with cmd_Start and true on writeStart", () => {
			tags.Device_Status_INT.value = 4;
			const wrapper = shallow(<Controls tags={tags} writeTag={writeTag} />);
			wrapper.find(".start-button").simulate("click", null);
			expect(writeTag).toHaveBeenCalledWith("cmd_Start", true);
	
		});
	
		it("should run the writeTag function with cmd_Stop and true on writeStop", () => {
			tags.Device_Status_INT.value = 0;
			const wrapper = shallow(<Controls tags={tags} writeTag={writeTag} />);
			wrapper.find(".stop-button").simulate("click", null);
			expect(writeTag).toHaveBeenCalledWith("cmd_Stop", true);
		});

		it("should disable set button on flowrate select button if parameter already selected", () => {
			tags.sts_PID_Control.value = 0;
			const wrapper = shallow(<Controls tags={tags} writeTag={writeTag} />);
			expect(wrapper.find(".flowrate-select").hasClass("disabled")).toBeTruthy();
		});

		it("should disable set button on fluidlevel select button if parameter already selected", () => {
			tags.sts_PID_Control.value = 1;
			const wrapper = shallow(<Controls tags={tags} writeTag={writeTag} />);
			expect(wrapper.find(".fluidlevel-select").hasClass("disabled")).toBeTruthy();
		});

		it("should disable set button on tubingpressure select button if parameter already selected", () => {
			tags.sts_PID_Control.value = 2;
			const wrapper = shallow(<Controls tags={tags} writeTag={writeTag} />);
			expect(wrapper.find(".tubingpressure-select").hasClass("disabled")).toBeTruthy();
		});

		it("should disable set button on frequency select button if parameter already selected", () => {
			tags.sts_PID_Control.value = 3;
			const wrapper = shallow(<Controls tags={tags} writeTag={writeTag} />);
			expect(wrapper.find(".frequency-select").hasClass("disabled")).toBeTruthy();
		});
	});
	describe("control setpoints", () => {
		let writeTag;
		let wrapper;
		beforeEach(() => {
			writeTag = jest.fn((tag, val) => {
				return {tag, val};
			});
			wrapper = shallow(<Controls tags={tags} writeTag={writeTag} />);
		});

		it("should update setpoint state on setpoint change", () => {
			wrapper.find(".flowrate-input").simulate("change", {target: {value: 100.0 }});
			expect(wrapper.state().setpoints.flowrate).toEqual(100.0);

			wrapper.find(".fluidlevel-input").simulate("change", {target: {value: 200.0 }});
			expect(wrapper.state().setpoints.fluidlevel).toEqual(200.0);

			wrapper.find(".tubingpressure-input").simulate("change", {target: {value: 300.0 }});
			expect(wrapper.state().setpoints.tubingpressure).toEqual(300.0);

			wrapper.find(".frequency-input").simulate("change", {target: {value: 400.0 }});
			expect(wrapper.state().setpoints.frequency).toEqual(400.0);
		});

		it("should call writeTag with the setpoint tag and the value", () => {
			wrapper.find(".flowrate-input").simulate("change", {target: {value: 100.0 }});
			wrapper.find(".flowrate-submit").simulate("click", {preventDefault: jest.fn()});
			expect(writeTag).toBeCalledWith("cfg_PID_FlowSP", 100.0);

			wrapper.find(".fluidlevel-input").simulate("change", {target: {value: 200.0 }});
			wrapper.find(".fluidlevel-submit").simulate("click", {preventDefault: jest.fn()});
			expect(writeTag).toBeCalledWith("cfg_PID_FluidLevelSP", 200.0);

			wrapper.find(".tubingpressure-input").simulate("change", {target: {value: 300.0 }});
			wrapper.find(".tubingpressure-submit").simulate("click", {preventDefault: jest.fn()});
			expect(writeTag).toBeCalledWith("cfg_PID_TubingPressureSP", 300.0);

			wrapper.find(".frequency-input").simulate("change", {target: {value: 400.0 }});
			wrapper.find(".frequency-submit").simulate("click", {preventDefault: jest.fn()});
			expect(writeTag).toBeCalledWith("cfg_PID_ManualSP", 400.0);
		});

		it("should call writeTag with cfg_PID_* and true when selecting control parameter", () => {
			wrapper.find(".flowrate-select").simulate("click", {preventDefault: jest.fn()});
			expect(writeTag).toHaveBeenCalledWith("cfg_PID_Flow", true);

			wrapper.find(".fluidlevel-select").simulate("click", {preventDefault: jest.fn()});
			expect(writeTag).toHaveBeenCalledWith("cfg_PID_FluidLevel", true);

			wrapper.find(".tubingpressure-select").simulate("click", {preventDefault: jest.fn()});
			expect(writeTag).toHaveBeenCalledWith("cfg_PID_TubingPressure", true);

			wrapper.find(".frequency-select").simulate("click", {preventDefault: jest.fn()});
			expect(writeTag).toHaveBeenCalledWith("cfg_PID_Manual", true);
		});

	});

	it("should map state to props", () => {
		expect(mapStateToProps({ tags: "tags", extra: "extra" })).toEqual({ tags: "tags" });
	});


});