func main() {
	app = cli.NewApp()
	app.Name = "facecrop"
	app.Usage = "crop face from image by rect info arguments"

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "path, p",
			Value: "",
			Usage: "path of image file.",
		},
		cli.StringFlag{
			Name:  "rect, r",
			Value: "",
			Usage: "rect to crop. (format: left,top,right,bottom)",
		},
		cli.StringFlag{
			Name:  "out, o",
			Value: "out",
			Usage: "path of output file.",
		},
	}

	app.Action = func(c *cli.Context) {
		pathArg := c.String("path")
		rectArg := c.String("rect")
		outArg := c.String("out")

		if len(pathArg) == 0 || len(rectArg) == 0 {
			println("path and rect are required.")
			cli.ShowAppHelp(c)
			return
		}

		fmt.Printf("Processing image file path: %s\n", pathArg)

		file_in, err := os.Open(pathArg)
		if err != nil {
			log.Fatal("File open error. err: ", err)
			os.Exit(255)
		}
		defer file_in.Close()

		image_in, err := jpeg.Decode(file_in)
		if err != nil {
			log.Fatal("Image decode error. err: ", err)
			os.Exit(255)
		}

		faceInfo, err := facecheck.ParseFaceInfo(rectArg)
		if err != nil {
			fmt.Printf("Parse Rect error. err: %v, rect: %s\n", err, rectArg)
		}

		faceInfo_json, _ := json.Marshal(faceInfo)
		fmt.Printf("Face info is: %s\n", faceInfo_json)

		writeImageFunc := func(r *facecheck.Rect, suffix string, i int) {
			fmt.Printf("%s rect is: %v\n", suffix, r)
			rect := image.Rect(r.Left, r.Top, r.Right, r.Bottom)
			file_out, err := os.Create(outArg + "_" + suffix + strconv.Itoa(i) + ".jpg")
			if err != nil {
				log.Fatal("File create error. err: ", err)
				os.Exit(255)
			}
			defer file_out.Close()
			croped := utils.CropImage(image_in, rect)
			jpeg.Encode(file_out, croped, &jpeg.Options{100})
		}

		for i, v := range faceInfo.Faces {
			writeImageFunc(&v, "Face", i)
		}
		for i, v := range faceInfo.Heads {
			writeImageFunc(&v, "Head", i)
		}

		fmt.Println("DONE!")
	}

	app.Run(os.Args)
}
func procImage(img *model.ImageInfo, mongo *m.Mongo, p pool.Pool) {
	image_json, _ := json.Marshal(img)
	log.Printf("Processing image. image: %s", image_json)
	tcpConn, err := p.Get()
	if err != nil {
		log.Printf("Get connection from pool error. err: %v", err)
		return
	}
	defer tcpConn.Close()

	filePath := filepath.Join(config.ImageFilePath, img.File_path)
	log.Printf("Processing. path: %s", filePath)
	message := facecheck.BuildMessage(filePath)
	if message == nil {
		log.Printf("Build message Error.")
		return
	}

	writer := bufio.NewWriter(tcpConn)
	n, err := writer.Write(message)
	if err != nil {
		log.Printf("Write message to FaceRec server Error. err: = %v", err)
		return
	}
	if n != len(message) {
		log.Printf("Write message to FaceRec size Error. expect: %d, wrote: %d", len(message), n)
		return
	}
	err = writer.Flush()
	if err != nil {
		log.Printf("Flush message to FaceRec server Error. err: = %v", err)
		return
	}

	dataBuffer := bytes.Buffer{}
	b := make([]byte, 256)
	totalLen := int32(18)
	messageBody := ""
	isComplete := false
	for {
		n, err := tcpConn.Read(b)
		if err != nil {
			if err != io.EOF {
				log.Printf("Read message from FaceRec server Error. err: = %v", err)
			}
			return
		}
		dataBuffer.Write(b[:n])
		log.Printf("Read message from FaceRec server. n: %d, buffer: %x", n, dataBuffer.Bytes())
		if int32(dataBuffer.Len()) >= totalLen {
			totalLen, messageBody, isComplete = facecheck.ParseResult(dataBuffer.Bytes())
			log.Printf(`Read message from FaceRec server. totalLen: %d, messageBody: "%s", isComplete: %v`, totalLen, messageBody, isComplete)
			if isComplete {
				break
			}
		}
	}
	img.Has_face = (len(messageBody) != 0)
	img.Face_info = messageBody
	img.Face_checked = true

	if img.Has_face == false {
		log.Printf("NO FACE: %v", img)
		return
	} else {
		log.Printf("FOUND FACE: %v", img)
	}

	file_in, err := os.Open(filePath)
	if err != nil {
		log.Fatal("File open error. err: ", err)
		os.Exit(255)
	}
	defer file_in.Close()

	image_in, err := jpeg.Decode(file_in)
	if err != nil {
		log.Fatal("Image decode error. err: ", err)
		os.Exit(255)
	}
	file_out, err := os.Create("Original.jpg")
	if err != nil {
		log.Fatal("File create error. err: ", err)
		os.Exit(255)
	}
	defer file_out.Close()
	jpeg.Encode(file_out, image_in, &jpeg.Options{100})

	faceInfo, err := facecheck.ParseFaceInfo(img.Face_info)
	if err != nil {
		fmt.Printf("Parse Rect error. err: %v, rect: %s\n", err, img.Face_info)
	}
	faceInfo_json, _ := json.Marshal(faceInfo)
	fmt.Printf("Face info is: %s\n", faceInfo_json)

	writeImageFunc := func(r *facecheck.Rect, suffix string, i int) {
		fmt.Printf("%s rect is: %v\n", suffix, r)
		rect := image.Rect(r.Left, r.Top, r.Right, r.Bottom)
		file_out, err := os.Create("Out_" + suffix + strconv.Itoa(i) + ".jpg")
		if err != nil {
			log.Fatal("File create error. err: ", err)
			os.Exit(255)
		}
		defer file_out.Close()
		croped := utils.CropImage(image_in, rect)
		jpeg.Encode(file_out, croped, &jpeg.Options{100})
	}

	for i, v := range faceInfo.Faces {
		writeImageFunc(&v, "Face", i)
	}
	for i, v := range faceInfo.Heads {
		writeImageFunc(&v, "Head", i)
	}
}