// Path: code/exercise_2/solution/src/main/java/com/frankmoley/talks/spring/intro/aspect/LoggableAspect.java
// @Aspect
// public class LoggableAspect {
// 
//     private static final Logger LOGGER = LoggerFactory.getLogger("AuditLogger");
// 
//     @Pointcut("@annotation(Loggable)")
//     public void executeLogging(){}
// 
//     @Around("executeLogging()")
//     public Object adviseLogging(ProceedingJoinPoint joinPoint) throws Throwable{
//         StopWatch stopWatch = new StopWatch();
//         stopWatch.start();
//         Object returnValue = null;
//         try {
//             returnValue = joinPoint.proceed();
//             return returnValue;
//         }finally {
//             stopWatch.stop();
//             StringBuilder message = new StringBuilder();
//             message.append("method=").append(joinPoint.getSignature().getName()).append("|");
//             message.append("time=").append(stopWatch.getTotalTimeMillis()).append("ms|");
//             Object[] args = joinPoint.getArgs();
//             if(null!=args && args.length>0){
//                 message.append("args={");
//                 boolean first=true;
//                 Arrays.asList(args).forEach(arg->{
//                     if(!first){
//                         message.append("|");
//                     }
//                     message.append(arg);
//                 });
//                 message.append("}");
//             }
//             LOGGER.info(message.toString());
// 
//         }
// 
//     }
// }
// 
// Path: code/exercise_3/exercise/src/main/java/com/frankmoley/talks/spring/intro/data/repository/ItemRepository.java
// @Repository
// public class ItemRepository {
//     //TODO later
// }
// 
// Path: code/exercise_2/solution/src/main/java/com/frankmoley/talks/spring/intro/data/repository/PersonRepository.java
// public class PersonRepository {
//     //TODO Later
// }
// 
// Path: code/exercise_4/solution/src/main/java/com/frankmoley/talks/spring/intro/service/InventoryService.java
// @Service
// public class InventoryService {
// 
//     private final ItemRepository itemRepository;
//     private final PersonRepository personRepository;
// 
//     @Autowired
//     public InventoryService(ItemRepository itemRepository, PersonRepository personRepository){
//         super();
//         this.itemRepository = itemRepository;
//         this.personRepository = personRepository;
//     }
// 
//     public Inventory getInventory(long personId){
//         return new Inventory();
//     }
// 
//     public Inventory updateInventory(Inventory inventory){
//         return inventory;
//     }
// 
//     public DetailedInventoryItem getDetailedInventoryItem(long personId, long itemId){
//         return new DetailedInventoryItem();
//     }
// 
// }
// 
// Path: code/exercise_4/exercise/src/main/java/com/frankmoley/talks/spring/intro/service/UserService.java
// @Service
// public class UserService {
// 
//     private final PersonRepository personRepository;
// 
//     @Autowired
//     public UserService(PersonRepository personRepository){
//         super();
//         this.personRepository = personRepository;
//     }
// 
//     @Loggable
//     public User getUser(String emailAddress){
//         User user = new User();
//         user.setUsername("BigLebowski");
//         user.setPersonId(UUID.randomUUID().toString());
//         return user;
//     }
// }


import com.frankmoley.talks.spring.intro.aspect.LoggableAspect;
import com.frankmoley.talks.spring.intro.data.repository.ItemRepository;
import com.frankmoley.talks.spring.intro.data.repository.PersonRepository;
import com.frankmoley.talks.spring.intro.service.InventoryService;
import com.frankmoley.talks.spring.intro.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.PropertySource;
package com.frankmoley.talks.spring.intro.config;


@Configuration
@PropertySource("classpath:application.properties")
@EnableAspectJAutoProxy
public class ApplicationConfig {

    @Bean
    public PersonRepository personRepository(){
        return new PersonRepository();
    }

    @Bean
    public ItemRepository itemRepository(){
        return new ItemRepository();
    }

    @Bean
    public InventoryService inventoryService(){
        return new InventoryService(itemRepository(), personRepository());
    }

    @Bean
    public LoggableAspect loggableAspect(){return new LoggableAspect();}

    @Bean
    public UserService userService(){return new UserService(personRepository());}


    public static void main(String[] args){
        ApplicationContext context = new  AnnotationConfigApplicationContext(ApplicationConfig.class);
// Path: code/exercise_2/solution/src/main/java/com/frankmoley/talks/spring/intro/aspect/LoggableAspect.java
// @Aspect
// public class LoggableAspect {
// 
//     private static final Logger LOGGER = LoggerFactory.getLogger("AuditLogger");
// 
//     @Pointcut("@annotation(Loggable)")
//     public void executeLogging(){}
// 
//     @Around("executeLogging()")
//     public Object adviseLogging(ProceedingJoinPoint joinPoint) throws Throwable{
//         StopWatch stopWatch = new StopWatch();
//         stopWatch.start();
//         Object returnValue = null;
//         try {
//             returnValue = joinPoint.proceed();
//             return returnValue;
//         }finally {
//             stopWatch.stop();
//             StringBuilder message = new StringBuilder();
//             message.append("method=").append(joinPoint.getSignature().getName()).append("|");
//             message.append("time=").append(stopWatch.getTotalTimeMillis()).append("ms|");
//             Object[] args = joinPoint.getArgs();
//             if(null!=args && args.length>0){
//                 message.append("args={");
//                 boolean first=true;
//                 Arrays.asList(args).forEach(arg->{
//                     if(!first){
//                         message.append("|");
//                     }
//                     message.append(arg);
//                 });
//                 message.append("}");
//             }
//             LOGGER.info(message.toString());
// 
//         }
// 
//     }
// }
// 
// Path: code/exercise_3/exercise/src/main/java/com/frankmoley/talks/spring/intro/data/repository/ItemRepository.java
// @Repository
// public class ItemRepository {
//     //TODO later
// }
// 
// Path: code/exercise_2/solution/src/main/java/com/frankmoley/talks/spring/intro/data/repository/PersonRepository.java
// public class PersonRepository {
//     //TODO Later
// }
// 
// Path: code/exercise_4/solution/src/main/java/com/frankmoley/talks/spring/intro/service/InventoryService.java
// @Service
// public class InventoryService {
// 
//     private final ItemRepository itemRepository;
//     private final PersonRepository personRepository;
// 
//     @Autowired
//     public InventoryService(ItemRepository itemRepository, PersonRepository personRepository){
//         super();
//         this.itemRepository = itemRepository;
//         this.personRepository = personRepository;
//     }
// 
//     public Inventory getInventory(long personId){
//         return new Inventory();
//     }
// 
//     public Inventory updateInventory(Inventory inventory){
//         return inventory;
//     }
// 
//     public DetailedInventoryItem getDetailedInventoryItem(long personId, long itemId){
//         return new DetailedInventoryItem();
//     }
// 
// }
// 
// Path: code/exercise_4/exercise/src/main/java/com/frankmoley/talks/spring/intro/service/UserService.java
// @Service
// public class UserService {
// 
//     private final PersonRepository personRepository;
// 
//     @Autowired
//     public UserService(PersonRepository personRepository){
//         super();
//         this.personRepository = personRepository;
//     }
// 
//     @Loggable
//     public User getUser(String emailAddress){
//         User user = new User();
//         user.setUsername("BigLebowski");
//         user.setPersonId(UUID.randomUUID().toString());
//         return user;
//     }
// }


// Path: code/exercise_2/solution/src/main/java/com/frankmoley/talks/spring/intro/config/ApplicationConfig.java
import com.frankmoley.talks.spring.intro.aspect.LoggableAspect;
import com.frankmoley.talks.spring.intro.data.repository.ItemRepository;
import com.frankmoley.talks.spring.intro.data.repository.PersonRepository;
import com.frankmoley.talks.spring.intro.service.InventoryService;
import com.frankmoley.talks.spring.intro.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.PropertySource;

package com.frankmoley.talks.spring.intro.config;


@Configuration
@PropertySource("classpath:application.properties")
@EnableAspectJAutoProxy
public class ApplicationConfig {

    @Bean
    public PersonRepository personRepository(){
        return new PersonRepository();
    }

    @Bean
    public ItemRepository itemRepository(){
        return new ItemRepository();
    }

    @Bean
    public InventoryService inventoryService(){
        return new InventoryService(itemRepository(), personRepository());
    }

    @Bean
    public LoggableAspect loggableAspect(){return new LoggableAspect();}

    @Bean
    public UserService userService(){return new UserService(personRepository());}


    public static void main(String[] args){
        ApplicationContext context = new  AnnotationConfigApplicationContext(ApplicationConfig.class);
        InventoryService service = context.getBean(InventoryService.class);