package com.hessianhealth.common.core.RServe;

import org.math.R.RLogPanel;
import org.math.R.RserverConf;
import org.math.R.Rsession;
import org.rosuda.REngine.REXPMismatchException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.util.Properties;


/**
* Created by liangguannan on 2020/9/28.
* 1.享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用。
* 2.Rsession是对Rserve的封装,提供了更高层的API接口,包括Rserve服务器控制,多会话机制
*
* http://blog.fens.me/series-r/
*/

/**
* @Component: 标注Spring管理的Bean,使用@Component注解在一个类上,表示将此类标记为Spring容器中的一个Bean。
* 当组件不好归类的时候,我们可以使用这个注解进行标注,标识为一个Bean。
*/
@Component
public class RServeHelper {

private static Rsession rsession=null;

@Value("${rengine.RUrl}")
private String url;
private static String URL;
@Value("${rengine.RPort}")
private Integer port;
private static Integer PORT;

@PostConstruct
public void init(){
URL = url;
PORT = port;
}

/**
* 利用Rsession初始化RServe
* 具体Rsession的方法使用可以查看https://github.com/yannrichet/rsession
* Rsession中的set("...",...)方法的第二个参数为本地数据,一般为现成的数据,只能是本地的数据,如果放入字符串,那么该变量的值就为该字符串。
如果想要保存一个执行过程中产生的变量,可以使用eval()方法。例如eval("tmp <- head(test)")
* @return
* @throws IOException
*/
@Bean
private static Rsession initRserve() throws IOException {
//从配置文件中读取Rserve信息,IP.用户名.密码
/* RserverConf rconf=new RserverConf(URL,PORT,null,null,new Properties());
rsession = Rsession.newInstanceTry(System.out, rconf);*/
return rsession;
}

/**
* 创建Rsession单例
* @Bean 项目启动时初始化
* @return
* @throws IOException
*/
@Bean
public static Rsession RsessionInstance() throws IOException {
if(rsession==null){
rsession=initRserve();
}
return rsession;
}

/**
* 创建Rsession
* @return
*/
public static Rsession callRserve(){
RserverConf rconf = new RserverConf(URL,PORT,null,null,new Properties());
Rsession s = Rsession.newInstanceTry(System.out, rconf);
return s;
}


/**
* 测试
Rsession提供了一种简单的方式,让Java可以访问远程或本地的Rserve实例。Rsession是对Rserve的封装,提供了更高层的API接口,包括Rserve服务器控制,多会话机制,并支持Windows环境。

接口类
BusyListener: Notify the state of R engine
EvalListener: Notify the evaluation of R expression
Logger: Support R messages printing
UpdateObjectsListener: Notify the changing of R environment objects
功能类

Rdaemon: RServe的守护进程
RLogPanel: 显示R日志的空间
RObjectsPanel: 显示R变量的控件
RserverConf: 连接Rserve实例的配置文件
Rsession: 连接Rserve实例
StartRserve: 启动本地的Rserve
* @param s
*/

public void test(Rsession s){
try {
// 执行R脚本
double[] rand = s.eval("rnorm(5)").asDoubles();
System.out.println(rand);

// 创建一个R对象
s.set("demo", Math.random());
s.eval("ls()");

// 保存R运行时状态到文件
s.save(new File("./keyan/output/save.Rdata"), "demo");

// 删除R对象demo
s.rm("demo");
s.eval("ls()");

// 从文件加载R环境
s.load(new File("./keyan/output/save.Rdata"));
s.eval("ls()");
s.eval("print(demo)");

// 创建一个data.frame对象
s.set("df", new double[][] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }, { 10, 11, 12 } }, "x1", "x2", "x3");
double df$x1_3 = s.eval("df$x1[3]").asDouble();
System.out.println(df$x1_3);
s.rm("df");

//#创建数据框 data.frame 为自带包**
s.eval("z <- data.frame(sampleId=c('MGJ','MGJ','MGJ2','MGJ2'),subgroup=c('B cells','B cells','B cells, pro','Basophils'),proportion=c(0.0224543895212849,0.115263157894737,0.00272883205987837,0.00447368421052632))");
s.eval("print(z)");

// 生成一个图形文件
s.eval("getwd()");
s.toJPEG(new File("C:\\Users\\liangguannan\\Desktop\\plot.png"), 400, 400, "plot(rnorm(10))");

// 以HTML格式输出
String html = s.asHTML("summary(rnorm(100))");
System.out.println("------------:"+html);

// 以文本格式输出
String txt = s.asString("summary(rnorm(100))");
System.out.println(txt);

// 安装新类库
//System.out.println(s.installPackage("sensitivity", true));
} catch (REXPMismatchException e) {
e.printStackTrace();
}finally {
s.end();
}
}

/**
* 分布图测试
* @param s
*/
public static void barplot(Rsession s){
s.eval("library(jsonlite)");
s.eval("library(ggplot2)");
s.eval("library(cowplot)");
s.eval("library(data.table)");

s.eval("w <- data.table(sampleId=c('MGJ','MGJ','MGJ2','MGJ2'),subgroup=c('B cells','B cells','B cells','Basophils'),proportion=c(0.0224543895212849,0.115263157894737,0.00272883205987837,0.00447368421052632))");
s.eval("print(w)");

s.eval("barplotdownload=function(nw,cluster,type,height,base_width,dpi,path)\n" +
"{\n" +
" nw$proportion=round(as.numeric(nw$proportion),digits=3)\n" +
" if (type==\"horizontal\")\n" +
" {p=ggplot(subset(nw,sampleId%in%cluster),aes(subgroup,proportion,fill=sampleId))+geom_bar(stat=\"identity\",position=\"dodge\")+\n" +
" theme_bw()+theme(panel.grid.major=element_line(colour=NA),\n" +
" panel.background = element_rect(fill = \"transparent\",colour = NA),\n" +
" plot.background = element_rect(fill = \"transparent\",colour = NA),\n" +
" panel.grid.minor = element_blank())+\n" +
" theme(legend.title = element_blank(), axis.title = element_blank(), axis.text.x = element_text(angle = 45, hjust = 0.5, vjust = 0.5))\n" +
" } else {\n" +
" p=ggplot(data=subset(nw,sampleId%in%cluster),aes(x=sampleId,y=proportion,fill=subgroup))+geom_col(position=\"fill\")+\n" +
" theme_bw()+theme(panel.grid.major=element_line(colour=NA),\n" +
" panel.background = element_rect(fill = \"transparent\",colour = NA),\n" +
" plot.background = element_rect(fill = \"transparent\",colour = NA),\n" +
" panel.grid.minor = element_blank())+\n" +
" theme(legend.title = element_blank(),axis.title = element_blank(),\n" +
" axis.text.x = element_text(angle = 45, hjust = 0.5, vjust = 0.5))\n" +
" }\n" +
" \n" +
" setwd(path)\n" +
" \n" +
" save_plot(\"barplot.png\",p,base_height = height, base_width = base_width, dpi=dpi)\n" +
" save_plot(\"barplot.pdf\",p,base_height = height, base_width = base_width, dpi=dpi)\n" +
"}");

s.eval("barplotdownload(w,c(\"MGJ\",\"MGJ2\"),\"vertical\",10,20,100,\"/home/file\")");
}

/**
* 气泡图测试
* @param s
*/
public static void DotPlot(Rsession s){
//s.load(new File("C:\\Users\\liangguannan\\Desktop\\MGJ_MGJ2_Cluster_all.Rdata"));

s.eval("library(dplyr)");
s.eval("library(ggplot2)");
s.eval("library(cowplot)");

//s.eval("data.filt=get(load(\"C:\\Users\\liangguannan\\Desktop\\MGJ_MGJ2_Cluster_all.Rdata\"))");

s.eval("DotPlotdownload=function(datafilt,resolution,genes,cluster,color,height,base_width,dpi,path){\n" +
" DefaultAssay(datafilt) <- \"RNA\"\n" +
" Idents(data.filt)=resolution\n" +
" dotPlot<- DotPlot(data.filt, features=genes, idents=cluster, cols = c(\"lightgrey\", color))\n" +
" setwd(path)\n" +
" save_plot(\"dotplot.png\",dotPlot,base_height = height, base_width = base_width, dpi=dpi)\n" +
" save_plot(\"dotplot.pdf\",dotPlot,base_height = height, base_width = base_width, dpi=dpi)\n" +
"}");

s.eval("resolution=\"integrated_snn_res.0.8\"");
s.eval("genes=c(\"Elane\",\"Ctsg\",\"Ibsp\")");
s.eval("cluster=c(0,1,2,3,5,6)");
s.eval("color=\"red\"");
s.eval("path=\"/home/admin\"");

s.eval("DotPlotdownload(data,resolution,genes,cluster,color,10,20,300,path)");

}

/**
* 散点图
* @param s
*/
public static void dimplot(Rsession s){
s.eval("library(dplyr)");
s.eval("library(ggplot2)");
s.eval("library(cowplot)");

s.eval("datafilt=get(load(\"/home/data/projects/WHBIOBANKS003/result/result.20201119151044/standard_analysis/1_Data_QC_Statistics/Rdata/MGJ_MGJ2_Cluster_all.Rdata\"))");

s.eval("Dimplotdownload=function(data.filt,resolution,reduction,cluster,split,sizep,sizel,height,base_width,dpi,path)\n" +
"{\n" +
" Idents(data.filt)=resolution\n" +
" dim=FetchData(data.filt,vars=resolution,slot=\"data\")\n" +
" dim$cell=rownames(dim)\n" +
" dimr=dim[which(dim[,resolution] %in% cluster),]\n" +
" cell=dimr$cell\n" +
" \n" +
" setwd(path)\n" +
" \n" +
" if (split ==FALSE) {\n" +
" dimplotall=DimPlot(object = data.filt,cells=cell,reduction = reduction, label = TRUE,\n" +
" pt.size = sizep,label.size = sizel)\n" +
" \n" +
" \n" +
" save_plot(sprintf(\"Dimplotall_%s_.png\", reduction),dimplotall,base_height = height, base_width = base_width, dpi=dpi)\n" +
" save_plot(sprintf(\"Dimplotall_%s_.pdf\", reduction),dimplotall,base_height = height, base_width = base_width, dpi=dpi)\n" +
" } else {\n" +
" dimplotsplit=DimPlot(object = data.filt,cells=cell,reduction = reduction, label = FALSE,\n" +
" pt.size = sizep,label.size = sizel)+facet_wrap(~ident,scales=\"free\")\n" +
" \n" +
" save_plot(sprintf(\"Dimplotsplit_%s_.png\", reduction),dimplotsplit,base_height = height, base_width = base_width, dpi=dpi)\n" +
" save_plot(sprintf(\"Dimplotsplit_%s_.pdf\", reduction),dimplotsplit,base_height = height, base_width = base_width, dpi=dpi)}\n" +
" \n" +
"}");


s.eval("resolution=\"integrated_snn_res.0.8\"");
s.eval("genes=c(\"Elane\",\"Ctsg\",\"Ibsp\")");
s.eval("cluster=c(0,1,2,3,5,6)");
s.eval("path=\"/home/admin\"");
s.eval("reduction=\"tsne\"");
s.eval("split=FALSE");
s.eval("sizep=1");
s.eval("sizel=6");

s.eval("Dimplotdownload(datafilt,resolution,reduction,cluster,split,sizep,sizel,10,20,300,path)");
}

/**
* 小提琴图
* @param s
*/
public static void vlnPlot(Rsession s){
s.eval("library(dplyr)");

s.eval("VlnPlotdownload=function(datafilt,genes,cluster,base_height,base_width,dpi,path)\n" +
"{\n" +
" Idents(datafilt)=resolution\n" +
" dim=FetchData(data.filt,vars=resolution,slot=\"data\")\n" +
" dim$cell=rownames(dim)\n" +
" dimr=dim[which(dim[,resolution] %in% cluster),]\n" +
" cell=dimr$cell\n" +
" \n" +
" modify_vlnplot <- function(obj, feature, pt.size = 0, plot.margin = unit(c(-0.75, 0, -0.75, 0), \"cm\"),...) {\n" +
" p <- VlnPlot(obj, features = feature, pt.size = pt.size, ... ) +\n" +
" xlab(\"\") + ylab(feature) + ggtitle(\"\") +\n" +
" theme(legend.position = \"none\",\n" +
" axis.text.x = element_blank(),\n" +
" axis.text.y = element_blank(),\n" +
" axis.ticks.x = element_blank(),\n" +
" axis.ticks.y = element_line(),\n" +
" axis.title.y = element_text(size = rel(1), angle = 0, vjust = 0.5),\n" +
" plot.margin = plot.margin )\n" +
" return(p)\n" +
" }\n" +
" \n" +
" ## main function\n" +
" StackedVlnPlot <- function(obj, features, pt.size = 0, plot.margin = unit(c(-0.75, 0, -0.75, 0), \"cm\"), ...) {\n" +
" plot_list <- purrr::map(features, function(x) modify_vlnplot(obj = obj,feature = x, ...))\n" +
" plot_list[[length(plot_list)]]<- plot_list[[length(plot_list)]] +\n" +
" theme(axis.text.x=element_text(), axis.ticks.x = element_line())\n" +
" p <- patchwork::wrap_plots(plotlist = plot_list, ncol = 1)\n" +
" return(p)\n" +
" }\n" +
" \n" +
" DefaultAssay(datafilt) <- \"RNA\"\n" +
" \n" +
" data2=datafilt[,cell]\n" +
" plot=StackedVlnPlot(data2, genes, pt.size=0)\n" +
" \n" +
" setwd(path)\n" +
" \n" +
" save_plot(\"StackedVlnPlot.png\", plot, base_height = base_height,base_width = base_width, dpi=dpi)\n" +
" save_plot(\"StackedVlnPlot.pdf\", plot, base_height = base_height,base_width = base_width, dpi=dpi)\n" +
"}");

s.eval("resolution=\"integrated_snn_res.0.8\"");
s.eval("genes=c(\"Elane\",\"Ctsg\",\"Ibsp\")");
s.eval("cluster=c(0,1,2,3,5,6)");
s.eval("color=\"red\"");
s.eval("path=\"/home/admin\"");

s.eval("VlnPlotdownload(datafilt,resolution,genes,cluster,10,20,300,path)");
}

/**
* 热力图
* @param s
*/
public static void Heatmap(Rsession s){
s.eval("library(SCVIS)");
s.eval("datafilt=get(load(\"/home/data/projects/WHBIOBANKS003/result/result.20201119151044/standard_analysis/1_Data_QC_Statistics/Rdata/MGJ_MGJ2_Cluster_all.Rdata\"))");

s.eval("resolution=\"integrated_snn_res.0.8\"");
s.eval("cluster=c(0,1,2,3,5,6)");
s.eval("genes=c(\"Elane\",\"Ctsg\",\"Ibsp\")");
s.eval("path=\"/home/keyan/reportPDF\"");

s.eval("Heatmapdownload(datafilt,resolution,cluster,genes,8,16,300,path)");

}

/**
* @param args
*/
public static void main(String[] args) {
RserverConf rconf = new RserverConf("192.168.8.144", 6311, "conan", "conan", new Properties());
Rsession s = Rsession.newInstanceTry(System.out, rconf);

try {

//s.eval("help(package=\"SCVIS\")");
Heatmap(s);


System.exit(0);//避免JDWP Unable to get JNI 1.2 environment
} catch (Exception e) {
e.printStackTrace();
}finally {
s.close();
}


}
}