// Path: src/main/java/ch/rasc/s4ws/portfolio/Portfolio.java
// public class Portfolio {
// 
// 	private final Map<String, PortfolioPosition> positionLookup = new LinkedHashMap<>();
// 
// 	public List<PortfolioPosition> getPositions() {
// 		return new ArrayList<>(this.positionLookup.values());
// 	}
// 
// 	public void addPosition(PortfolioPosition position) {
// 		this.positionLookup.put(position.getTicker(), position);
// 	}
// 
// 	public PortfolioPosition getPortfolioPosition(String ticker) {
// 		return this.positionLookup.get(ticker);
// 	}
// 
// 	/**
// 	 * @return the updated position or null
// 	 */
// 	public PortfolioPosition buy(String ticker, int sharesToBuy) {
// 		PortfolioPosition position = this.positionLookup.get(ticker);
// 		if (position == null || sharesToBuy < 1) {
// 			return null;
// 		}
// 		position = new PortfolioPosition(position, sharesToBuy);
// 		this.positionLookup.put(ticker, position);
// 		return position;
// 	}
// 
// 	/**
// 	 * @return the updated position or null
// 	 */
// 	public PortfolioPosition sell(String ticker, int sharesToSell) {
// 		PortfolioPosition position = this.positionLookup.get(ticker);
// 		if (position == null || sharesToSell < 1 || position.getShares() < sharesToSell) {
// 			return null;
// 		}
// 		position = new PortfolioPosition(position, -sharesToSell);
// 		this.positionLookup.put(ticker, position);
// 		return position;
// 	}
// 
// }
// 
// Path: src/main/java/ch/rasc/s4ws/portfolio/PortfolioPosition.java
// public class PortfolioPosition {
// 
// 	private final String company;
// 
// 	private final String ticker;
// 
// 	private final double price;
// 
// 	private final int shares;
// 
// 	private final long updateTime;
// 
// 	public PortfolioPosition(String company, String ticker, double price, int shares) {
// 		this.company = company;
// 		this.ticker = ticker;
// 		this.price = price;
// 		this.shares = shares;
// 		this.updateTime = System.currentTimeMillis();
// 	}
// 
// 	public PortfolioPosition(PortfolioPosition other, int sharesToAddOrSubtract) {
// 		this.company = other.company;
// 		this.ticker = other.ticker;
// 		this.price = other.price;
// 		this.shares = other.shares + sharesToAddOrSubtract;
// 		this.updateTime = System.currentTimeMillis();
// 	}
// 
// 	public String getCompany() {
// 		return this.company;
// 	}
// 
// 	public String getTicker() {
// 		return this.ticker;
// 	}
// 
// 	public double getPrice() {
// 		return this.price;
// 	}
// 
// 	public int getShares() {
// 		return this.shares;
// 	}
// 
// 	public long getUpdateTime() {
// 		return this.updateTime;
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return "PortfolioPosition [company=" + this.company + ", ticker=" + this.ticker
// 				+ ", price=" + this.price + ", shares=" + this.shares + "]";
// 	}
// 
// }
// 
// Path: src/main/java/ch/rasc/s4ws/portfolio/service/Trade.java
// public enum TradeAction {
// 	Buy, Sell;
// }


import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import ch.rasc.s4ws.portfolio.Portfolio;
import ch.rasc.s4ws.portfolio.PortfolioPosition;
import ch.rasc.s4ws.portfolio.service.Trade.TradeAction;
/*
 * Copyright 2002-2013 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ch.rasc.s4ws.portfolio.service;




@Service
public class TradeServiceImpl implements TradeService {

	private static final Log logger = LogFactory.getLog(TradeServiceImpl.class);

	private final SimpMessageSendingOperations messagingTemplate;

	private final PortfolioService portfolioService;

	private final List<TradeResult> tradeResults = new CopyOnWriteArrayList<>();

	@Autowired
	public TradeServiceImpl(SimpMessageSendingOperations messagingTemplate,
			PortfolioService portfolioService) {
		this.messagingTemplate = messagingTemplate;
		this.portfolioService = portfolioService;
	}

	/**
	 * In real application a trade is probably executed in an external system, i.e.
	 * asynchronously.
	 */
	@Override
	public void executeTrade(Trade trade) {

		Portfolio portfolio = this.portfolioService.findPortfolio(trade.getUsername());
		String ticker = trade.getTicker();
		int sharesToTrade = trade.getShares();

// Path: src/main/java/ch/rasc/s4ws/portfolio/Portfolio.java
// public class Portfolio {
// 
// 	private final Map<String, PortfolioPosition> positionLookup = new LinkedHashMap<>();
// 
// 	public List<PortfolioPosition> getPositions() {
// 		return new ArrayList<>(this.positionLookup.values());
// 	}
// 
// 	public void addPosition(PortfolioPosition position) {
// 		this.positionLookup.put(position.getTicker(), position);
// 	}
// 
// 	public PortfolioPosition getPortfolioPosition(String ticker) {
// 		return this.positionLookup.get(ticker);
// 	}
// 
// 	/**
// 	 * @return the updated position or null
// 	 */
// 	public PortfolioPosition buy(String ticker, int sharesToBuy) {
// 		PortfolioPosition position = this.positionLookup.get(ticker);
// 		if (position == null || sharesToBuy < 1) {
// 			return null;
// 		}
// 		position = new PortfolioPosition(position, sharesToBuy);
// 		this.positionLookup.put(ticker, position);
// 		return position;
// 	}
// 
// 	/**
// 	 * @return the updated position or null
// 	 */
// 	public PortfolioPosition sell(String ticker, int sharesToSell) {
// 		PortfolioPosition position = this.positionLookup.get(ticker);
// 		if (position == null || sharesToSell < 1 || position.getShares() < sharesToSell) {
// 			return null;
// 		}
// 		position = new PortfolioPosition(position, -sharesToSell);
// 		this.positionLookup.put(ticker, position);
// 		return position;
// 	}
// 
// }
// 
// Path: src/main/java/ch/rasc/s4ws/portfolio/PortfolioPosition.java
// public class PortfolioPosition {
// 
// 	private final String company;
// 
// 	private final String ticker;
// 
// 	private final double price;
// 
// 	private final int shares;
// 
// 	private final long updateTime;
// 
// 	public PortfolioPosition(String company, String ticker, double price, int shares) {
// 		this.company = company;
// 		this.ticker = ticker;
// 		this.price = price;
// 		this.shares = shares;
// 		this.updateTime = System.currentTimeMillis();
// 	}
// 
// 	public PortfolioPosition(PortfolioPosition other, int sharesToAddOrSubtract) {
// 		this.company = other.company;
// 		this.ticker = other.ticker;
// 		this.price = other.price;
// 		this.shares = other.shares + sharesToAddOrSubtract;
// 		this.updateTime = System.currentTimeMillis();
// 	}
// 
// 	public String getCompany() {
// 		return this.company;
// 	}
// 
// 	public String getTicker() {
// 		return this.ticker;
// 	}
// 
// 	public double getPrice() {
// 		return this.price;
// 	}
// 
// 	public int getShares() {
// 		return this.shares;
// 	}
// 
// 	public long getUpdateTime() {
// 		return this.updateTime;
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return "PortfolioPosition [company=" + this.company + ", ticker=" + this.ticker
// 				+ ", price=" + this.price + ", shares=" + this.shares + "]";
// 	}
// 
// }
// 
// Path: src/main/java/ch/rasc/s4ws/portfolio/service/Trade.java
// public enum TradeAction {
// 	Buy, Sell;
// }


// Path: src/main/java/ch/rasc/s4ws/portfolio/service/TradeServiceImpl.java
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import ch.rasc.s4ws.portfolio.Portfolio;
import ch.rasc.s4ws.portfolio.PortfolioPosition;
import ch.rasc.s4ws.portfolio.service.Trade.TradeAction;

/*
 * Copyright 2002-2013 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ch.rasc.s4ws.portfolio.service;




@Service
public class TradeServiceImpl implements TradeService {

	private static final Log logger = LogFactory.getLog(TradeServiceImpl.class);

	private final SimpMessageSendingOperations messagingTemplate;

	private final PortfolioService portfolioService;

	private final List<TradeResult> tradeResults = new CopyOnWriteArrayList<>();

	@Autowired
	public TradeServiceImpl(SimpMessageSendingOperations messagingTemplate,
			PortfolioService portfolioService) {
		this.messagingTemplate = messagingTemplate;
		this.portfolioService = portfolioService;
	}

	/**
	 * In real application a trade is probably executed in an external system, i.e.
	 * asynchronously.
	 */
	@Override
	public void executeTrade(Trade trade) {

		Portfolio portfolio = this.portfolioService.findPortfolio(trade.getUsername());
		String ticker = trade.getTicker();
		int sharesToTrade = trade.getShares();

		PortfolioPosition newPosition = trade.getAction() == TradeAction.Buy