package com.huixinpn.dionysus.controller.course;

import com.huixinpn.dionysus.controller.util.PagingHelper;
import com.huixinpn.dionysus.domain.course.Course;
import com.huixinpn.dionysus.domain.course.CourseApproach;
import com.huixinpn.dionysus.domain.course.CourseCategory;
import com.huixinpn.dionysus.domain.user.Consultant;
import com.huixinpn.dionysus.domain.user.User;
import com.huixinpn.dionysus.dto.EntityCollectionData;
import com.huixinpn.dionysus.dto.EntityPageData;
import com.huixinpn.dionysus.dto.course.CourseCategoryData;
import com.huixinpn.dionysus.dto.course.CourseData;
import com.huixinpn.dionysus.dto.user.ConsultantData;
import com.huixinpn.dionysus.repository.course.CourseCategoryRepository;
import com.huixinpn.dionysus.repository.course.CourseRepository;
import com.huixinpn.dionysus.repository.tag.TagRepository;
import com.huixinpn.dionysus.repository.user.ConsultantRepository;
import com.huixinpn.dionysus.repository.user.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import java.util.Collection;
import java.util.List;

@RestController
@RequestMapping(value="/controllers")
public class CourseController {
  @Autowired
  private CourseRepository courseRepository;

  @Autowired
  private TagRepository tagRepository;

  @Autowired
  private UserRepository userRepository;

  @Autowired
  private CourseCategoryRepository courseCategoryRepository;

  @Autowired
  private ConsultantRepository consultantRepository;


  @RequestMapping(value = "/courses/{id}/reg", method = RequestMethod.GET)
  public ResponseEntity<String> registerColurse(@PathVariable Long id) {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    Object principle = authentication.getPrincipal();
    if (!(principle instanceof User)) {
      return new ResponseEntity<>(HttpStatus.FORBIDDEN);
    }
    User login = (User) authentication.getPrincipal();
    User reloaded = userRepository.findOne(login.getId());
    Course course = courseRepository.findOne(id);
    if (course != null &&
        (course.getCapacity() == null || course.getUsers().size() < course.getCapacity()) &&
        !reloaded.getCourses().contains(course)) {
      course.getUsers().add(reloaded);
      courseRepository.save(course);
    }
    return new ResponseEntity<>("{}",HttpStatus.OK);
  }

  @RequestMapping(value = "/courses", method = RequestMethod.GET)
  public
  @ResponseBody
  EntityPageData<CourseData> listCourses(@RequestParam(value = "page", required = false) Integer page,
                                         @RequestParam(value = "size", required = false) Integer size) {
    PageRequest paging = PagingHelper.getPageRequest(page, size);
    Page<Course> pagedCourses = courseRepository.findAll(paging);
    return new EntityPageData<>(pagedCourses, CourseData.class);
  }

  @RequestMapping(value = "/courses/categories", method = RequestMethod.GET)
  public
  @ResponseBody
  Collection<CourseCategoryData> listCategories() {
    List<CourseCategory> categories = courseCategoryRepository.findAll();
    return new EntityCollectionData<>(categories, CourseCategoryData.class).toDTOCollection();
  }

  @RequestMapping(value = "/courses/categories/{id}", method = {RequestMethod.PUT, RequestMethod.POST})
  public
  @ResponseBody
  ResponseEntity<String> updateCategory(@RequestBody CourseCategoryData data, @PathVariable Long id) {
    if (!id.equals(data.getId())) {
      return new ResponseEntity(HttpStatus.BAD_REQUEST);
    }
    CourseCategory category = courseCategoryRepository.save(data.toEntity());
    return new ResponseEntity("{}",HttpStatus.OK);
  }

  @RequestMapping(value = "/courses/consultants", method = RequestMethod.GET)
  public
  @ResponseBody
  Collection<ConsultantData> listConsultants() {
    List<Consultant> consultants = consultantRepository.findAll();
    return new EntityCollectionData<>(consultants, ConsultantData.class).toDTOCollection();
  }

  @RequestMapping(value = "/courses/category/{cid}", method = RequestMethod.GET)
  public
  @ResponseBody
  EntityPageData<CourseData> searchCoursesByCategory(@RequestParam(value = "page", required = false) Integer page,
                                                     @RequestParam(value = "size", required = false) Integer size,
                                                     @RequestParam(value = "approach", required = false) CourseApproach approach,
                                                     @PathVariable Long cid) {
    PageRequest paging = PagingHelper.getPageRequest(page, size);
    Page<Course> pagedCourses;
    if (approach != null) {
      pagedCourses = courseRepository.findByCategoryAndApproach(new CourseCategory(cid), approach, paging);
    } else {
      pagedCourses = courseRepository.findByCategory(new CourseCategory(cid), paging);
    }
    return new EntityPageData<>(pagedCourses, CourseData.class);
  }

  @RequestMapping(value = "/courses/tag/{tid}", method = RequestMethod.GET)
  public
  @ResponseBody
  EntityPageData<CourseData> searchCoursesByTag(@RequestParam(value = "page", required = false) Integer page,
                                                @RequestParam(value = "size", required = false) Integer size,
                                                @RequestParam(value = "approach", required = false) CourseApproach approach,
                                                @PathVariable Long tid) {
    PageRequest paging = PagingHelper.getPageRequest(page, size);
    Page<Course> courses;
    if (approach != null) {
      courses = courseRepository.findByTagAndApproach(tid, approach, paging);
    } else {
      courses = courseRepository.findByTag(tid, paging);
    }
    return new EntityPageData<>(courses, CourseData.class);
  }

  @RequestMapping(value = "/courses/{id}", method = RequestMethod.GET)
  public
  @ResponseBody
  CourseData listCourse(@PathVariable Long id) {
    Course course = courseRepository.findOne(id);
    return new CourseData(course);
  }

  @RequestMapping(value = "/courses/{id}", method = {RequestMethod.PUT, RequestMethod.POST})
  public
  @ResponseBody
  ResponseEntity<String> updateCourse(@RequestBody CourseData data, @PathVariable Long id) {
    if (!id.equals(data.getId())) {
      return new ResponseEntity(HttpStatus.BAD_REQUEST);
    }
    Course updating = data.toEntity();
    courseRepository.save(updating);
    return new ResponseEntity("{}",HttpStatus.OK);
  }

  @RequestMapping(value = "/courses", method = RequestMethod.POST)
  public
  @ResponseBody
  ResponseEntity<String> addCourse(@RequestBody CourseData data) {
    Course adding = data.toEntity();
    courseRepository.save(adding);
    return new ResponseEntity<>("{}",HttpStatus.OK);
  }

}

@@ -1488,17 +1488,19 @@
 ng(value
-=
+ = 
 %22/contro
@@ -1848,16 +1848,72 @@
 itory;%0A%0A
+  public static final String EMPTY_JSON_OBJECT = %22%7B%7D%22;%0A%0A
 %0A  @Requ
@@ -2742,37 +2742,51 @@
 esponseEntity%3C%3E(
-%22%7B%7D%22,
+EMPTY_JSON_OBJECT, 
 HttpStatus.OK);%0A
@@ -4050,37 +4050,51 @@
  ResponseEntity(
-%22%7B%7D%22,
+EMPTY_JSON_OBJECT, 
 HttpStatus.OK);%0A
@@ -6878,21 +6878,35 @@
 eEntity(
-%22%7B%7D%22,
+EMPTY_JSON_OBJECT, 
 HttpStat
@@ -7185,13 +7185,27 @@
 y%3C%3E(
-%22%7B%7D%22,
+EMPTY_JSON_OBJECT, 
 Http

add const string EMPTY_JSON_OBJECT