Kannan Govindan

136 papers Journal 134Unranked 2
YearRankTypeTitle / Venue / Authors
2026 J jnl
J. Oper. Res. Soc.
Jighyasu Gaur, Mehdi Amini, Kannan Govindan
2026 J jnl
Int. J. Prod. Res.
Fotios Petropoulos, Henk Akkermans, O. Zeynep Aksin, Imran Ali, Mohamed Zied Babai, Ana Barbosa-Póvoa, Olga Battaïa, Maria Besiou, Nils Boysen, Stephen Brammer, Alistair Brandon-Jones, Dirk Briskorn, Tyson R. Browning, Paul Buijs, Piera Centobelli, Andrea Chiarini, Paul Cousins, Elizabeth A. Cudney, Andrew Davies, Steven J. Day, René de Koster, Rommert Dekker, Juliano Denicol, Mélanie Despeisse, Stephen M. Disney, Alexandre Dolgui, Linh Duong, Malek El-Qallali, Behnam Fahimnia, Fatemeh Fakhredin, Stanley B. Gershwin, Salar Ghamat, Vaggelis Giannikas, Christoph H. Glock, Janet Godsell, Kannan Govindan, Claire Hannibal, Anders Haug, Tomislav Hernaus, Juliana Hsuan, Dmitry Ivanov, Marianne Jahre, Björn Johansson, Madan Shankar Kalidoss, Argyris Kanellopoulos, Devika Kannan, Elif Karul, Konstantinos V. Katsikopoulos, Ayse Begüm Kilic-Ararat, Rainer Kolisch, Maximilian Koppenberg, Maneesh Kumar, Yong-Hong Kuo, Andrew Kusiak, Michael A. Lewis, Stanley Frederick W. T. Lim, Veronique Limère, Jiyin Liu, Omid Maghazei, Matija Maric, Joern Meissner, Miranda Meuwissen, Pietro Micheli, Samudaya Nanayakkara, Bengü Nur Özdemir, Thanos Papadopoulos, Stephen Pavelin, Srinath Perera, Wendy Phillips, Dennis Prak, Hubert Pun, Sharfah Ahmad Qazi, Usha Ramanathan, Gerald Reiner, Ewout Reitsma, Jens K. Roehrich, Nada R. Sanders, Joseph Sarkis, Nico André Schmid, Christoph G. Schmidt, Andreas Schroeder, Kostas Selviaridis, Stefan Seuring, Chuan Shi, Byung-Gak Son, Martin Spring, Brian Squire, Wendy van der Valk, Dirk Pieter van Donk, Geert-Jan van Houtum, Miriam Wilhelm, Finn Wynstra, Ting Zheng
2025 J jnl
Ann. Oper. Res.
Chunguang Bai, Kannan Govindan, Ahmet Satir, Hong Yan
2025 J jnl
Comput. Chem. Eng.
Naeme Zarrinpoor, Kannan Govindan
2025 J jnl
Ann. Oper. Res.
Vahid Kayvanfar, Roberto Baldacci, Kannan Govindan
2025 J jnl
Ann. Oper. Res.
Kannan Govindan
2025 J jnl
Ann. Oper. Res.
Jacky Chen, Chee Peng Lim, Kim Hua Tan, Kannan Govindan, Ajay Kumar
2025 J jnl
Comput. Ind. Eng.
Ahmed Mohammed, Kannan Govindan, Nasiru Zubairu, Jacob Pratabaraj, Ahmed Zainul Abideen
2025 J jnl
Comput. Ind. Eng.
Ahmed Mohammed, Fatma Alzahraa Al Balushi, Nasiru Zubairu, Kannan Govindan
2025 J jnl
Int. J. Intell. Syst.
Ahm Shamsuzzoha, Khuram Shahzad, Essi Nousiainen, Mikko Ranta, Petri Helo, Kannan Govindan
2025 J jnl
J. Ind. Inf. Integr.
Zhen-Song Chen, Kou-Dan Chen, Kannan Govindan, Maxwell Fordjour Antwi-Afari
2025 J jnl
CoRR
Fotios Petropoulos, Henk Akkermans, O. Zeynep Aksin, Imran Ali, Mohamed Zied Babai, Ana Barbosa-Póvoa, Olga Battaïa, Maria Besiou, Nils Boysen, Stephen Brammer, Alistair Brandon-Jones, Dirk Briskorn, Tyson R. Browning, Paul Buijs, Piera Centobelli, Andrea Chiarini, Paul Cousins, Elizabeth A. Cudney, Andrew Davies, Steven J. Day, René de Koster, Rommert Dekker, Juliano Denicol, Mélanie Despeisse, Stephen M. Disney, Alexandre Dolgui, Linh Duong, Malek El-Qallali, Behnam Fahimnia, Fatemeh Fakhredin, Stanley B. Gershwin, Salar Ghamat, Vaggelis Giannikas, Christoph H. Glock, Janet Godsell, Kannan Govindan, Claire Hannibal, Anders Haug, Tomislav Hernaus, Juliana Hsuan, Dmitry Ivanov, Marianne Jahre, Björn Johansson, Madan Shankar Kalidoss, Argyris Kanellopoulos, Devika Kannan, Elif Karul, Konstantinos V. Katsikopoulos, Ayse Begüm Kilic-Ararat, Rainer Kolisch, Maximilian Koppenberg, Maneesh Kumar, Yong-Hong Kuo, Andrew Kusiak, Michael A. Lewis, Stanley Frederick W. T. Lim, Veronique Limère, Jiyin Liu, Omid Maghazei, Matija Maric, Joern Meissner, Miranda Meuwissen, Pietro Micheli, Samudaya Nanayakkara, Bengü Nur Özdemir, Thanos Papadopoulos, Stephen Pavelin, Srinath Perera, Wendy Phillips, Dennis Prak, Hubert Pun, Sharfah Ahmad Qazi, Usha Ramanathan, Gerald Reiner, Ewout Reitsma, Jens K. Roehrich, Nada R. Sanders, Joseph Sarkis, Nico André Schmid, Christoph G. Schmidt, Andreas Schroeder, Kostas Selviaridis, Stefan Seuring, Chuan Shi, Byung-Gak Son, Martin Spring, Brian Squire, Wendy van der Valk, Dirk Pieter van Donk, Geert-Jan van Houtum, Miriam Wilhelm, Finn Wynstra, Ting Zheng
2024 J jnl
IEEE Trans. Engineering Management
Joana R. B. Silva, Fernando A. F. Ferreira, Kannan Govindan, Neuza C. M. Q. F. Ferreira, Ricardo J. C. Correia
2024 J jnl
J. Oper. Res. Soc.
Hossein Reyhani Yamchi, Younis Jabarzadeh, Kannan Govindan, Hannan Amoozad Mahdiraji
2024 J jnl
Comput. Ind. Eng.
Niamat Ullah Ibne Hossain, Ifaz Ahmed, Sudipta Chowdhury, Kannan Govindan, Raed M. Jaradat
2024 J jnl
IEEE Trans. Engineering Management
Akansha Jain, Jyoti Dhingra Darbari, Kannan Govindan, Usha Ramanathan, P. C. Jha
2024 J jnl
Comput. Ind. Eng.
Kannan Govindan, Fereshteh Sadeghi Naieni Fard, Fahimeh Asgari, Shahryar Sorooshian, Hassan Mina
2024 J jnl
IEEE Trans. Engineering Management
Lu Xiao, Zhen-Song Chen, Kannan Govindan, Miroslaw J. Skibniewski
2024 J jnl
Eur. J. Oper. Res.
Lei Fang, Yanlin Li, Kannan Govindan
2024 J jnl
J. Big Data
Raghu Raman, Debidutta Pattnaik, Hiran H. Lathabai, Chandan Kumar, Kannan Govindan, Prema Nedungadi
2024 J jnl
IEEE Trans. Consumer Electron.
Arun Kumar Sangaiah, Xizhao Wang, Mohammad S. Obaidat, Patrick C. K. Hung, Kannan Govindan
2024 J jnl
IEEE Trans. Engineering Management
Kannan Govindan
2024 J jnl
Ind. Manag. Data Syst.
Nan Chen, Jianfeng Cai, Devika Kannan, Kannan Govindan
2024 J jnl
Ann. Oper. Res.
Chunguang Bai, Kannan Govindan, Dileep Dhavale
2024 J jnl
Eur. J. Oper. Res.
Constança Paúl, Fernando A. F. Ferreira, Kannan Govindan, Neuza C. M. Q. F. Ferreira
2024 J jnl
Inf. Sci.
Tong-Yuan Wang, Zhen-Song Chen, Xian-Jia Wang, Kannan Govindan, Miroslaw J. Skibniewski
2024 J jnl
Bus. Process. Manag. J.
Dian Palupi Restuputri, Ilyas Masudin, Auraria Putri Septira, Kannan Govindan, Widayat Widayat
2024 J jnl
IEEE Trans. Engineering Management
Kannan Govindan
2023 J jnl
IEEE Trans. Engineering Management
Gonçalo F. Estupendo, Fernando A. F. Ferreira, Kannan Govindan, Ricardo J. C. Correia, Leandro Ferreira Pereira, Ieva Meidute-Kavaliauskiene
2023 J jnl
Ann. Oper. Res.
Wai Peng Wong, Kim Hua Tan, Kannan Govindan, Di Li, Ajay Kumar
2023 J jnl
Electron. Commer. Res. Appl.
Kannan Govindan, Georgios Arampatzis
2023 J jnl
Expert Syst. Appl.
Salman Nazari Shirkouhi, Mahdokht Tavakoli, Kannan Govindan, Saeed Mousakhani
2023 J jnl
Eng. Appl. Artif. Intell.
Abtin Ijadi Maghsoodi, Ali Ebadi Torkayesh, Lincoln C. Wood, Enrique Herrera-Viedma, Kannan Govindan
2023 J jnl
J. Oper. Res. Soc.
Hannan Amoozad Mahdiraji, Kannan Govindan, Saba Madadi, Jose Arturo Garza-Reyes
2023 conf
IEEM
Ahmed Mohammed, Salwa Al Balushi, Kannan Govindan, Nasiru Zubairu
2023 J jnl
Decis. Sci.
Kannan Govindan, Suresh P. Sethi, T. C. E. Cheng, Susan Feng Lu
2023 J jnl
Ann. Oper. Res.
Sajjad Rahmanzadeh, Mir Saman Pishvaee, Kannan Govindan
2023 J jnl
Eng. Appl. Artif. Intell.
Arunodaya Raj Mishra, Pratibha Rani, Muhammet Deveci, Ilgin Gökasar, Dragan Pamucar, Kannan Govindan
2023 J jnl
Comput. Ind. Eng.
Ahmed Mohammed, Kannan Govindan, Nasiru Zubairu, Jacob Pratabaraj, Ahmed Zainul Abideen
2023 J jnl
Int. J. Prod. Res.
Kannan Govindan, Arash Khalili Nasr, Mohammad Saeed Heidary, Saeede Nosrati-Abarghooee, Hassan Mina
2023 J jnl
Eur. J. Oper. Res.
Mohammad Fattahi, Esmaeil Keyvanshokooh, Devika Kannan, Kannan Govindan
2023 J jnl
Int. J. Prod. Res.
Muhammad Shujaat Mubarik, Simonov Kusi-Sarpong, Kannan Govindan, Sharfuddin Ahmed Khan, Adegboyega Oyedijo
2023 J jnl
Oper. Res.
Mohammad Mahdi Nasiri, Amir Khaleghi, Kannan Govindan, Ali Bozorgi-Amiri
2023 J jnl
Ind. Manag. Data Syst.
Imran Ali, Mohamed Gamal Aboelmaged, Kannan Govindan, Mohsin Malik
2022 J jnl
Ann. Oper. Res.
Seyed Hossein Razavi Hajiagha, Jalil Heidary Dahooie, Ieva Meidute-Kavaliauskiene, Kannan Govindan
2022 J jnl
Ann. Oper. Res.
Mahmood Vahdani, Zeinab Sazvar, Kannan Govindan
2022 J jnl
Expert Syst. Appl.
Niamat Ullah Ibne Hossain, Nazmus Sakib, Kannan Govindan
2022 J jnl
Expert Syst. Appl.
Tong-Yuan Wang, Zhen-Song Chen, Kannan Govindan, Kwai-Sang Chin
2022 J jnl
Decis. Sci.
Mohammad Fattahi, Kannan Govindan
2022 J jnl
Expert Syst. Appl.
Negar Karimi, Mohammad Reza Feylizadeh, Kannan Govindan, Morteza Bagherpour
2022 J jnl
Expert Syst. Appl.
Tong-Yuan Wang, Zhen-Song Chen, Kannan Govindan, Kwai-Sang Chin
2022 J jnl
Int. J. Prod. Res.
Pankaj Gupta, Kannan Govindan, Mukesh Kumar Mehlawat, Anisha Khaitan
2022 J jnl
Ann. Oper. Res.
Zhen-Song Chen, Sheng Wu, Kannan Govindan, Xian-Jia Wang, Kwai-Sang Chin, Luis Martíinez
2022 J jnl
Oper. Res.
Maryam Shoaeinaeini, Kannan Govindan, Donya Rahmani
2022 J jnl
Kybernetes
Lu Xiao, Zhi-Ying Wu, Song-Ling Zhang, Zhen-Song Chen, Kannan Govindan
2022 J jnl
Ann. Oper. Res.
Nomita Pachar, Jyoti Dhingra Darbari, Kannan Govindan, P. C. Jha
2022 J jnl
Comput. Ind. Eng.
Helena Carvalho, Bardia Naghshineh, Kannan Govindan, Virgílio Cruz-Machado
2022 J jnl
Eur. J. Oper. Res.
Fernando A. F. Ferreira, Ronald W. Spahr, Mark A. Sunderman, Kannan Govindan, Ieva Meidute-Kavaliauskiene
2021 J jnl
Int. J. Prod. Res.
Jafar Heydari, Kannan Govindan, Zahra Basiri
2021 J jnl
Comput. Ind. Eng.
Shahrooz Shahparvari, Hamed Soleimani, Kannan Govindan, Behrooz Bodaghi, Mahshid Taherian Fard, Hamid Jafari
2021 J jnl
Comput. Ind. Eng.
Kannan Govindan, Arash Khalili Nasr, Parisa Mostafazadeh, Hassan Mina
2021 J jnl
Comput. Ind. Eng.
Ali Mahmoudi, Kannan Govindan, Davood Shishebori, Reza Mahmoudi
2021 J jnl
Int. J. Prod. Res.
Mohammad Fattahi, Kannan Govindan, Mehdi Farhadkhani
2021 J jnl
Expert Syst. Appl.
Zhen-Song Chen, Xuan Zhang, Kannan Govindan, Xian-Jia Wang, Kwai-Sang Chin
2020 J jnl
Ann. Oper. Res.
Bahman Naderi, Kannan Govindan, Hamed Soleimani
2020 J jnl
Ann. Oper. Res.
Shiva Zandkarimkhani, Hassan Mina, Mehdi Biuki, Kannan Govindan
2020 J jnl
J. Oper. Res. Soc.
Xiaochen Sun, Yancong Zhou, Yongjian Li, Kannan Govindan, Xiaonan Han
2020 J jnl
Comput. Ind. Eng.
Arunodaya Raj Mishra, Pratibha Rani, Abbas Mardani, Kamal Raj Pardasani, Kannan Govindan, Melfi Alrasheedi
2020 J jnl
Int. J. Prod. Res.
Casper Selmer Frandsen, Martin Mathias Nielsen, Atanu Chaudhuri, Jayanth Jayaram, Kannan Govindan
2020 J jnl
Int. J. Prod. Res.
Surendra M. Gupta, Askiner Güngör, Kannan Govindan, Eren Özceylan, Can Berk Kalayci, Rajesh Piplani
2020 J jnl
Ann. Oper. Res.
Ata Allah Taleizadeh, Kannan Govindan, Nasim Ebrahimi
2020 J jnl
Symmetry
Pratibha Rani, Kannan Govindan, Arunodaya Raj Mishra, Abbas Mardani, Melfi Alrasheedi, D. S. Hooda
2019 J jnl
Int. J. Prod. Res.
Nima Kazemi, Nikunja Mohan Modak, Kannan Govindan
2019 J jnl
Ann. Oper. Res.
Kannan Govindan, Vernika Agarwal, Jyoti Dhingra Darbari, P. C. Jha
2019 J jnl
Comput. Oper. Res.
Kannan Govindan, Ahmad Jafarian, Vahid Nourbakhsh
2019 J jnl
Eur. J. Oper. Res.
Yongjian Li, Lipan Feng, Kannan Govindan, Fangchao Xu
2019 J jnl
Comput. Oper. Res.
Lei Xu, Xiaoran Shi, Peng Du, Kannan Govindan, Zhenchao Zhang
2018 J jnl
Comput. Oper. Res.
Mohammad Fattahi, Kannan Govindan, Esmaeil Keyvanshokooh
2018 J jnl
Ann. Oper. Res.
Seyed Habib A. Rahmati, Abbas Ahmadi, Kannan Govindan
2018 J jnl
Int. J. Prod. Res.
Kannan Govindan, Mia Hasanagic
2018 J jnl
Comput. Oper. Res.
Kannan Govindan, T. C. E. Cheng
2018 J jnl
Ann. Oper. Res.
Somayeh Soheilirad, Kannan Govindan, Abbas Mardani, Edmundas Kazimieras Zavadskas, Mehrbakhsh Nilashi, Norhayati Zakuan
2018 J jnl
J. Oper. Res. Soc.
Mahsa Noori-daryan, Ata Allah Taleizadeh, Kannan Govindan
2018 J jnl
Int. J. Prod. Res.
Lei Xu, Yongjian Li, Kannan Govindan, Xiaohang Yue
2017 J jnl
Int. J. Prod. Res.
Anass Cherrafi, Said Elfezazi, Kannan Govindan, Jose Arturo Garza-Reyes, Khalid Benhida, Ahmed Mokhlis
2017 J jnl
Comput. Ind. Eng.
Hamed Soleimani, Kannan Govindan, Hamid Saghafi, Hamid Jafari
2017 J jnl
Ann. Oper. Res.
Tsan-Ming Choi, Kannan Govindan, Xiang Li, Yongjian Li
2017 J jnl
Ann. Oper. Res.
Mohammad Fattahi, Kannan Govindan
2017 J jnl
Eur. J. Oper. Res.
Xianpei Hong, Kannan Govindan, Lei Xu, Peng Du
2017 J jnl
Eur. J. Oper. Res.
Lipan Feng, Kannan Govindan, Chunfa Li
2017 J jnl
Eur. J. Oper. Res.
Kannan Govindan, Mohammad Fattahi, Esmaeil Keyvanshokooh
2016 J jnl
Asia Pac. J. Oper. Res.
Prerna Manik, Anshu Gupta, P. C. Jha, Kannan Govindan
2016 J jnl
Ind. Manag. Data Syst.
Kannan Govindan, Roohollah Khodaverdi, Amin Vafadarnikjoo
2016 J jnl
Ann. Oper. Res.
Morteza Lalmazloumian, Kuan Yew Wong, Kannan Govindan, Devika Kannan
2016 J jnl
Ann. Oper. Res.
Masoud Esmaeilikia, Behnam Fahimnia, Joseph Sarkis, Kannan Govindan, Arun Kumar, John Mo
2016 J jnl
Int. J. Syst. Assur. Eng. Manag.
Vernika Agarwal, Kannan Govindan, Jyoti Dhingra Darbari, P. C. Jha
2016 J jnl
Eur. J. Oper. Res.
Kannan Govindan, Martin Brandt Jepsen
2016 J jnl
Ann. Oper. Res.
Kannan Govindan
2016 J jnl
Comput. Ind. Eng.
Anjali Awasthi, Kannan Govindan
2016 J jnl
Ann. Oper. Res.
Kannan Govindan, R. Sivakumar
2016 J jnl
IEEE Trans. Cybern.
Kannan Govindan, Ahmad Jafarian, Mostafa E. Azbari, Tsan-Ming Choi
2016 J jnl
J. Oper. Res. Soc.
Kannan Govindan, Martin Brandt Jepsen
2016 J jnl
Ann. Oper. Res.
Masoud Esmaeilikia, Behnam Fahimnia, Joseph Sarkis, Kannan Govindan, Arun Kumar, John Mo
2015 J jnl
Comput. Oper. Res.
Kannan Govindan, Ahmad Jafarian, Vahid Nourbakhsh
2015 J jnl
Eur. J. Oper. Res.
Lei Xu, Yongjian Li, Kannan Govindan, Xiaolin Xu
2015 J jnl
Expert Syst. Appl.
Kannan Govindan, Roohollah Khodaverdi, Amin Vafadarnikjoo
2015 J jnl
Comput. Oper. Res.
Lei Xu, Kannan Govindan, Xiangzhi Bu, Yilin Yin
2015 J jnl
Comput. Oper. Res.
Jie Wei, Kannan Govindan, Yongjian Li, Jing Zhao
2015 J jnl
Eur. J. Oper. Res.
Kannan Govindan, Hamed Soleimani, Devika Kannan
2015 J jnl
Comput. Oper. Res.
Kannan Govindan, T. C. E. Cheng
2015 J jnl
Eur. J. Oper. Res.
Kannan Govindan
2014 J jnl
J. Oper. Res. Soc.
Xiang Li, Yongjian Li, Kannan Govindan
2014 J jnl
Eur. J. Oper. Res.
Kannan Govindan, Joseph Sarkis, Charbel José Chiappetta Jabbour, Qinghua Zhu, Yong Geng
2014 J jnl
Int. J. Appl. Math. Comput. Sci.
D. Thresh Kumar, Hamed Soleimani, Kannan Govindan
2014 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Yongjian Li, Lei Xu, Tsan-Ming Choi, Kannan Govindan
2014 J jnl
Eur. J. Oper. Res.
Marcus Brandenburg, Kannan Govindan, Joseph Sarkis, Stefan Seuring
2014 J jnl
Eur. J. Oper. Res.
Hamed Soleimani, Kannan Govindan
2014 J jnl
Eur. J. Oper. Res.
Kannan Govindan, Maria Nicoleta Popiuc
2014 J jnl
Eur. J. Oper. Res.
Wei Hu, Yongjian Li, Kannan Govindan
2013 J jnl
IEEE Trans. Engineering Management
Ali Diabat, Tarek Abdallah, Abbas Al-Refaie, Davor Svetinovic, Kannan Govindan
2013 conf
SocProS (2)
Kanika Gandhi, P. C. Jha, Kannan Govindan, Diego Galar
2012 J jnl
Comput. Ind. Eng.
Kannan Govindan, Ali Diabat, Maria Nicoleta Popiuc
2012 J jnl
Int. J. Manuf. Technol. Manag.
P. Senthil, T. Selvaraj, Kannan Govindan, R. Jeyapaul
2011 J jnl
Int. J. Adv. Oper. Manag.
B. Shahul Hamid Khan, Kannan Govindan
2010 J jnl
Ind. Manag. Data Syst.
Kannan Govindan, Devika Kannan, A. Noorul Haq
2010 J jnl
Int. J. Adv. Oper. Manag.
B. Shahul Hamid Khan, Kannan Govindan, R. Jeyapaul
2010 J jnl
Int. J. Bus. Perform. Supply Chain Model.
Ch. V. V. S. N. V. Prasad, Kannan Govindan, D. M. Kulkarni
2009 J jnl
Int. J. Serv. Technol. Manag.
Kannan Govindan, Palaniappan Murugesan, A. Noorul Haq
2009 J jnl
Int. J. Serv. Technol. Manag.
P. Sasikumar, Kannan Govindan, A. Noorul Haq
2009 J jnl
Int. J. Serv. Technol. Manag.
Vinay V. Panicker, Kannan Govindan, P. Sasikumar
2009 J jnl
Int. J. Bus. Perform. Supply Chain Model.
Kishore K. Pochampally, Surendra M. Gupta, Kannan Govindan
2009 J jnl
Int. J. Serv. Technol. Manag.
Kannan Govindan, Palaniappan Murugesan, P. Senthil, A. Noorul Haq
2009 J jnl
Int. J. Bus. Perform. Supply Chain Model.
Rakesh Verma, Saroj Koul, Kannan Govindan
2008 J jnl
Int. J. Inf. Syst. Supply Chain Manag.
Kannan Govindan, P. Senthil, P. Sasikumar, Vinay V. Panicker
2008 J jnl
Comput. Ind. Eng.
Kannan Govindan, P. Sasikumar, Vinay V. Panicker
2006 J jnl
Int. J. Inf. Technol. Decis. Mak.
A. Noorul Haq, Kannan Govindan
redb/extractors/capa.py
← Index redb/extractors/capa.py python
from dataclasses import asdict
import inspect
import json
import subprocess
import magic
from magika import Magika
from typing import Any, Dict, List, Tuple
from datetime import datetime, timezone

from redb.extractors.enum import Tag
from redb.models.dataclasses import CAPA
from redb.extractors.extractor import Extractor
from dotenv import load_dotenv
import os

load_dotenv(override=True)

class CAPAExtractor(Extractor):

    def __init__(
        self,
        filepath,
        log,
        exporters=None,
        index_prefix=None,
        elastic_index=None,
        known_benign=False,
        known_malicious=False,
    ):
        super().__init__(
            filepath, 
            log, 
            exporters,
            index_prefix, 
            elastic_index, 
            known_benign, 
            known_malicious
        )
        self.capa = None
        self.elastic_index = self.index_prefix + "-capa"

    def _replace_empty_keys(self, dictionary, replacement="default_empty_key"):
        """
        Replace empty keys in a dictionary with a specified replacement.

        Args:
        dictionary (dict): The input dictionary
        replacement (str): The replacement for empty keys (default: 'empty_key')

        Returns:
        dict: A new dictionary with empty keys replaced
        """
        # tmp_dict = {}
        # for k, v in dictionary.items():
        #     if k == '':
        #         tmp_dict[replacement] = dictionary[k]
        #     else:
        #         tmp_dict[k] = dictionary[k]
        # return tmp_dict
        return {(replacement if k == "" else k): v for k, v in dictionary.items()}

    def _extract_capa(self):
        self.log.debug(inspect.currentframe().f_code.co_name)
        TIMEOUT = int(os.getenv("CAPA_TIMEOUT")) # 5 minutes in seconds
        capa_command = [os.getenv("CAPA_PATH"), "-j", self.filepath] # COMMENT FOR TESTING ON MAC

        import signal

        # try:
        #     result = subprocess.run(
        #         capa_command, capture_output=True, text=True, check=True, timeout=TIMEOUT
        #     )
        # except subprocess.TimeoutExpired:
        #     self.log.error(f"The capa command timed out after {TIMEOUT} seconds")
        #     return {}
        # except subprocess.CalledProcessError as e:
        #     self.log.error(f"Error running capa: {e}")
        #     return {}

        # try:
        #     capa_output = json.loads(result.stdout)
        # except json.JSONDecodeError as e:
        #     self.log.error("Error parsing capa output: {e}")
        #     return {}

        # Create a process group for easier termination of all child processes
        try:
            # Start the process in a new process group
            process = subprocess.Popen(
                capa_command,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True,
                preexec_fn=os.setsid  # Use os.setsid() to create a new process group
            )
            
            # Implement timeout handling manually
            try:
                stdout, stderr = process.communicate(timeout=TIMEOUT)
                # Process completed within timeout
                if process.returncode != 0:
                    self.log.error(f"Error running capa, return code: {process.returncode}, stderr: {stderr}")
                    return {}
            except subprocess.TimeoutExpired:
                # Kill the entire process group on timeout
                self.log.warning(f"The capa command timed out after {TIMEOUT} seconds, terminating process group")
                
                try:
                    # Send SIGTERM to the entire process group
                    os.killpg(process.pid, signal.SIGTERM)
                    
                    # Give it a moment to terminate gracefully
                    try:
                        process.wait(timeout=3)
                    except subprocess.TimeoutExpired:
                        # If it's still running after 3 seconds, send SIGKILL
                        self.log.warning("Process didn't terminate with SIGTERM, sending SIGKILL")
                        os.killpg(process.pid, signal.SIGKILL)
                        
                    process.wait()  # Make sure process resources are fully cleaned up
                except (ProcessLookupError, OSError) as e:
                    self.log.warning(f"Error while killing process: {e}")
                    
                return {}
                
            try:
                capa_output = json.loads(stdout)
            except json.JSONDecodeError as e:
                self.log.error(f"Error parsing capa output: {e}")
                return {}

            capa_dump = {}  # dictionalry of capabilities
            capabilities = set()  # list of capabilities
            namespaces = set()  # list of namespaces
            attack_dump = {}  # dictionary of tuples [tactic](technique, technique_id)
            tactics = set()  # list of tactics
            techniques = set()  # list of techniques
            techniques_id = set()  # list of techniques_id
            mbc_dump = {}  # dictionary of tuples [objective](behavior, behavior_id)
            mbc_objectives = set()  # list of objectives
            mbc_behaviors = set()  # list of behaviors
            mbc_behaviors_id = set()  # list of behaviors_id

            if isinstance(capa_output, dict) and "rules" in capa_output:
                rules = capa_output["rules"]
                if isinstance(rules, dict):
                    for rule_name, rule_data in rules.items():
                        if isinstance(rule_data, dict) and "meta" in rule_data:
                            meta = rule_data["meta"]
                            if isinstance(meta, dict):
                                # Process capabilities
                                namespace = meta.get("namespace", "").lower()
                                # if namespace != 'lib':
                                if namespace not in capa_dump:
                                    capa_dump[namespace] = []
                                    namespaces.add(namespace)
                                capa_dump[namespace].append(rule_name)
                                capabilities.add(rule_name)

                                # Process ATTACK information
                                if "attack" in meta:
                                    for attack_entry in meta["attack"]:
                                        tactic = attack_entry.get("tactic", "")
                                        technique = attack_entry.get("technique", "")
                                        id = attack_entry.get("id", "")
                                        if tactic and technique:
                                            if tactic in attack_dump:
                                                attack_dump[tactic].append((technique, id))
                                            else:
                                                attack_dump[tactic] = [(technique, id)]
                                            tactics.add(tactic)
                                            techniques.add(technique)
                                            techniques_id.add(id)

                                # Process MBC information
                                if "mbc" in meta:
                                    for mbc_entry in meta["mbc"]:
                                        objective = mbc_entry.get("objective", "")
                                        behavior = mbc_entry.get("behavior", "")
                                        id = mbc_entry.get("id", "")
                                        if objective and behavior:
                                            if objective in mbc_dump:
                                                mbc_dump[objective].append((behavior, id))
                                            else:
                                                mbc_dump[objective] = [(behavior, id)]
                                            mbc_objectives.add(objective)
                                            mbc_behaviors.add(behavior)
                                            mbc_behaviors_id.add(id)

            # return {
            #     'capabilities_all': json.dumps(capabilities_all, indent=2),
            #     'capabilities': list(capabilities),
            #     'namespaces': list(namespaces),
            #     'attack': json.dumps(attack, indent=2),
            #     'tactics': list(tactics),
            #     'techniques': list(techniques),
            #     'techniques_id': list(techniques_id),
            #     'mbc': json.dumps(mbc, indent=2),
            #     'mbc_objectives': list(mbc_objectives),
            #     'mbc_behaviors': list(mbc_behaviors),
            #     'mbc_behaviors_id': list(mbc_behaviors_id)
            # }

            capa_dump = self._replace_empty_keys(capa_dump)
            attack_dump = self._replace_empty_keys(attack_dump)
            mbc_dump = self._replace_empty_keys(mbc_dump)
            self.capa = CAPA(
                json.dumps(capa_dump, indent=2),
                list(capabilities),
                list(namespaces),
                json.dumps(attack_dump, indent=2),
                list(tactics),
                list(techniques),
                list(techniques_id),
                json.dumps(mbc_dump, indent=2),
                list(mbc_objectives),
                list(mbc_behaviors),
                list(mbc_behaviors_id),
            )
            self.log.debug(f"CAPA dump: {self.capa})")
            
        except Exception as e:
            self.log.error(f"Unexpected error in CAPA extraction: {str(e)}")
            # Try to clean up any process if possible
            if 'process' in locals() and process.poll() is None:
                try:
                    os.killpg(process.pid, signal.SIGKILL)
                    process.wait()
                except:
                    pass
            return {}

    def prepare_export_data(self, exporter_type: str) -> Any:
        if exporter_type == "ElasticsearchExporter":
            return self.capa
        elif exporter_type == "ClickHouseExporter":
            current_time = datetime.now(timezone.utc)
            
            # Prepare data for multiple tables
            tables_data = {
                'multi_table': True,  # Flag for multi-table export
                
                # Raw data table
                'raw': {
                    'table': 'redb_capa',
                    'data': [[
                        self.sha256,
                        self.md5,
                        self.sha1,
                        current_time,
                        self.capa.capa_dump,  # capa_dump
                        self.capa.attack_dump,            # attack_dump
                        self.capa.mbc_dump                # mbc_dump
                    ]],
                    'column_names': [
                        'sha256', 'md5', 'sha1', 'analysis_date',
                        'capa_dump', 'attack_dump', 'mbc_dump'
                    ],
                    'column_type_names': [
                        'FixedString(64)', 'FixedString(32)', 'FixedString(40)',
                        'DateTime64(3, \'UTC\')',
                        'JSON', 'JSON', 'JSON'
                    ]
                },
                
                # Capabilities table
                'capabilities': {
                    'table': 'redb_capa_capabilities',
                    'data': [
                        [self.sha256, self.md5, self.sha1, current_time, namespace, capability]
                        for namespace, capabilities in json.loads(self.capa.capa_dump).items()
                        for capability in capabilities
                    ],
                    'column_names': [
                        'sha256', 'md5', 'sha1', 'analysis_date',
                        'namespace', 'capability'
                    ],
                    'column_type_names': [
                        'FixedString(64)', 'FixedString(32)', 'FixedString(40)',
                        'DateTime64(3, \'UTC\')',
                        'LowCardinality(String)', 'LowCardinality(String)'
                    ]
                },
                
                # MITRE ATT&CK table
                'attack': {
                    'table': 'redb_capa_attack',
                    'data': [
                        [self.sha256, self.md5, self.sha1, current_time, 
                         tactic, technique[0], technique[1]]  # technique[0] is the name, technique[1] is the ID
                        for tactic, techniques in json.loads(self.capa.attack_dump).items()
                        for technique in techniques
                    ],
                    'column_names': [
                        'sha256', 'md5', 'sha1', 'analysis_date',
                        'tactic', 'technique', 'technique_id'
                    ],
                    'column_type_names': [
                        'FixedString(64)', 'FixedString(32)', 'FixedString(40)',
                        'DateTime64(3, \'UTC\')',
                        'LowCardinality(String)', 'LowCardinality(String)', 
                        'LowCardinality(String)'
                    ]
                },
                
                # MBC table
                'mbc': {
                    'table': 'redb_capa_mbc',
                    'data': [
                        [self.sha256, self.md5, self.sha1, current_time,
                         objective, behavior[0], behavior[1]]  # behavior[0] is the name, behavior[1] is the ID
                        for objective, behaviors in json.loads(self.capa.mbc_dump).items()
                        for behavior in behaviors
                    ],
                    'column_names': [
                        'sha256', 'md5', 'sha1', 'analysis_date',
                        'objective', 'behavior', 'behavior_id'
                    ],
                    'column_type_names': [
                        'FixedString(64)', 'FixedString(32)', 'FixedString(40)',
                        'DateTime64(3, \'UTC\')',
                        'LowCardinality(String)', 'LowCardinality(String)',
                        'LowCardinality(String)'
                    ]
                }
            }
            
            return tables_data

    def get_clickhouse_table(self) -> str:
        return "redb_capa"  # Return the main table name

    def extract(self):
        self.log.debug(inspect.currentframe().f_code.co_name)
        try:
            self._extract_capa()
            return self.capa  # Return the extracted data instead of exporting directly
        except Exception as e:
            self.log.error(f"Error extracting CAPA: {e}")
            return None

    def tag(self):
        return Tag.CAPA.value